PEP 301 – Distutils 的软件包索引和元数据
- 作者:
- Richard Jones <richard at python.org>
- 状态:
- 最终
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建:
- 2002年10月24日
- Python 版本:
- 2.3
- 历史记录:
- 2002年11月8日
摘要
本 PEP 提出对 Distutils 打包系统 [1] 的一些扩展。这些增强功能包括一个中央软件包索引服务器、用于将软件包信息提交到索引的工具以及对软件包元数据的扩展,以包含 Trove [2] 信息。
本 PEP 未涉及软件包依赖关系问题。它也没有涉及 PEP 243 中描述的软件包的存储和下载问题。它也没有提出 PEP 262 中描述的本地软件包数据库。
现有的软件包存储库,例如 Vaults of Parnassus [3]、CPAN [4] 和 PAUSE [5] 将在本领域作为现有技术进行调查。
基本原理
Python 程序员长期以来一直需要一种简单的方法来发现可供他们使用的现有模块和系统。可以说,这些系统在其他语言中的存在对它们的普及做出了重大贡献。Catalog-SIG 的存在以及那里的大量讨论表明,有大量用户认识到这种需求。
将 Distutils 打包系统引入 Python 简化了分发可共享代码的过程,并包含了捕获软件包元数据机制,但除了将其与软件包一起发布之外,对元数据几乎没有其他操作。
指向索引的界面应托管在 python.org 域名下,使其具有现有的目录工作所不具备的合法性。
向目录提交信息的界面应尽可能简单 - 希望对于大多数用户来说只是一个命令行。
由于此类系统的复杂性,未解决软件包依赖关系问题。PEP 262 提出了一种这样的系统,但截至撰写本文时,该 PEP 仍未完成。
未解决软件包分发(在中央服务器上存储)问题,因为它们需要对存储和带宽的可用性做出假设,而我无法做出这些假设。PEP 243 仍在开发中,正在解决这些问题以及更多其他问题。本提案被认为与 PEP 243 中的提案兼容,并且是其补充。
规范
规范分为三个部分:Web 界面、Distutils register 命令 和 Distutils Trove 分类。
Web 界面
Web 界面是在一个简单的存储库上实现的。该界面可通过 python.org 域名访问,可以直接访问或作为 packages.python.org 访问。
存储库包含所有元数据字段的列。(名称、版本) 对用作唯一键。对现有 (名称、版本) 的额外提交将导致执行 更新 操作。
Web 界面实现了以下命令/界面
- index
- 列出已知的软件包,可以选择进行过滤。还有一个额外的 HTML 页面 search,向用户呈现一个表单,用于自定义索引视图。索引将包含类似于 Trove 界面设计第 4.3 节中提供的浏览界面。结果将被分页、按字母顺序排序,并且仅显示最新版本。最新版本信息将使用 Distutils LooseVersion 类确定。
- display
- 显示有关软件包的信息。所有字段都以纯文本显示。“url”(或“home_page”)字段是超链接。
- submit
- 接受有关软件包的元数据的 POST 提交。“name” 和 “version” 字段是必填字段,因为它们唯一地标识索引中的条目。Submit 将自动确定是创建新条目还是更新现有条目。元数据在适当的地方进行正确性检查 - 特别是 Trove 鉴别符与允许的集合进行比较。更新将根据新提交的信息更新有关软件包的所有信息。
还将有一个提交/编辑表单,允许不使用 Distutils 的用户手动提交和更新。
- submit_pkg_info
- 接受 PKG-INFO 文件的 POST 提交,并执行与 submit 界面相同的函数。
- user
- 在索引中注册新用户。需要用户名、密码和电子邮件地址。密码将以 SHA 哈希的形式存储在索引数据库中。如果用户名已存在于数据库中
- 如果提供了有效的 HTTP 基本身份验证,则使用提交信息更新密码和电子邮件地址,或者
- 如果没有提供有效的身份验证,则通知用户登录名已被占用。
注册将是一个三步过程,包括
- 用户通过 Distutils register 命令或通过 Web 提交详细信息,
- 索引服务器向用户的电子邮件地址发送一封电子邮件,其中包含一个 URL,用于使用随机的一次性密钥确认注册,以及
- 用户访问带有密钥的 URL 并确认注册。
- roles
- 用于更改用户角色分配的界面。
- password_reset
- 使用提供的电子邮件地址作为密钥,这将重置用户的密码,并将新密码发送到用户的电子邮件地址。
submit 命令需要 HTTP 基本身份验证,最好通过 HTTPS 连接进行。
服务器界面将通过标准 HTTP 响应代码的子集指示命令的成功或失败
代码 | 含义 | Register 命令的影响 |
---|---|---|
200 | OK | 一切正常 |
400 | 错误请求 | 提交提供的数据格式错误 |
401 | 未授权 | 提供的用户名或密码不正确 |
403 | 禁止 | 用户无权更新软件包信息(不是所有者或维护者) |
用户角色
将为用户分配三个用户角色
- Owner
- 拥有软件包名称,可以为该名称分配 Maintainer 角色。第一个注册软件包信息的用户的被视为该软件包名称的所有者。管理员用户可以根据需要更改此设置。可以提交该软件包名称的更新。
- Maintainer
- 可以提交和更新特定软件包名称的信息。
- Admin
- 可以分配 Owner 角色和编辑用户详细信息。不特定于软件包名称。
索引存储(模式)
索引存储在一组关系数据库表中
- packages
- 列出软件包名称并保存软件包级元数据(目前仅为稳定版本)
- releases
- 每个软件包在 releases 中都有一个条目,用于发布的每个软件包版本。一行保存软件包 PKG-INFO 文件中提供的大部分信息。每个软件包(name、version)都有一行。
- trove_discriminators
- 列出 Trove 鉴别符文本,并为每个鉴别符分配一个唯一 ID。
- release_discriminators
- 每个条目将软件包(name、version)映射到 discriminator_id。我们映射到 releases 而不是 packages,因为鉴别符集可能在版本之间发生变化。
- journals
- 保存有关索引中软件包信息更改的信息。如果更改是特定于版本的,则此处列出对 packages、releases、roles 和 release_discriminators 表的更改,方法是按软件包 name 和 version 进行列出。
- users
- 保存我们的用户数据库 - 用户名、电子邮件地址和密码。
- roles
- 将 user_name 和 role_name 映射到 package_name。
另一个表 rego_otk 保存注册期间生成的一次性密钥,并且在索引本身的范围内不感兴趣。
Distutils register 命令
实现了一个额外的 Distutils 命令 register
,它将软件包元数据发布到中央索引。register 命令自动处理用户注册;用户可以选择以下三种选项
- 登录并提交软件包信息
- 注册为新的打包程序
- 发送密码提醒电子邮件
在设置了 $HOME
环境变量的系统上,将在退出时提示用户将其用户名/密码保存到其 $HOME
目录中的 .pypirc
文件中。
将向所有提交过有关软件包信息的用户发送有关软件包条目更改的通知。即,原始提交者和任何后续更新者。
register 命令将包含一个 --verify
选项,该选项执行对索引的测试提交,而不会实际提交数据。索引将照常执行其提交验证检查,并报告在正常提交期间会报告的任何错误。这对于验证 Trove 鉴别符的正确性很有用。
Distutils Trove 分类
Trove 的 discrimination 概念将添加到软件包作者可通过新属性“classifiers”使用的元数据集中。分类器列表可通过 Web 获取,并像这样添加到软件包中
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 中,classifiers 列表项将显示为单独的 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
- “success” 或 “fail”。
- X-Pypi-Reason
- 失败原因的描述,或成功情况下的其他信息。
但是,有人指出 [6] 这不是一个好的方案。
参考文献
版权
本文档已进入公有领域。
致谢
感谢 Anthony Baxter、Martin v. Loewis 和 David Goodger 在初稿阶段提供的鼓励和反馈。
感谢 A.M. Kuchling 的支持,包括托管第二个原型。
感谢 Greg Stein 建议 register 命令解释 HTTP 响应代码而不是自定义的 X-PyPI-* 头部。
感谢 Distutils 和 Catalog SIG 的众多参与者多年来提出的想法。
来源:https://github.com/python/peps/blob/main/peps/pep-0301.rst