跳转到主要内容

未提供项目描述

项目描述

笨蛋-pypi

Build Status PyPI version

笨蛋-pypi是一个简单的只读PyPI索引服务器生成器,完全由静态文件支持。它非常适合组织内部使用,这些组织有一大批自己的软件包,希望将其提供出去。

您可以看到一个示例生成的仓库

关于静态文件的一些牢骚(以及为什么您应该使用笨蛋-pypi)

笨蛋-pypi与其他PyPI实现的主要区别在于,笨蛋-pypi没有服务器组件。它只是一个脚本,给定一个Python软件包名称列表,生成大量静态文件,您可以从任何Web服务器或直接从S3提供。

能够完全从静态文件树中提供软件包库是非常神奇的。当您不需要担心运行大量的应用服务器(这些服务器正在处理大量可预先生成的只读查询)时,使其快速且高度可用变得非常简单。

Linux发行版已经在这方面做得很好了几十年。Debian有一个由数百个镜像组成的系统,整个系统完全由一些复杂的rsync命令提供支持。

对于PyPI仓库的维护者,笨蛋-pypi有一些不错的特性

  • 文件服务非常快。 nginx可以比您需要的速度更快地提供静态文件。实际上,在软件包数量或每个软件包的版本数量方面几乎没有限制。

  • 它非常简单。 没有复杂的WSGI应用程序需要部署,没有数据库,没有缓存。您只需要在拥有新软件包时运行脚本,您的索引服务器几秒钟后就可以准备好了。

有关选择此设计的原因,请参阅本仓库中的详细RATIONALE.md

使用方法

要使用dumb-pypi,您需要两样东西

  • 一个生成索引的脚本。(这就是本项目!)

  • 一个通用的Web服务器来提供生成的索引。

    这部分由您决定。例如,您可以将构建的索引同步到S3存储桶中,并直接从S3提供。您也可以在本地运行nginx来提供构建的索引。

我推荐的具有高可用性但仍然相当简单的部署是

  • 将所有软件包存储在S3中。

  • 设置一个cron作业(或等效的)根据S3中的软件包重新构建索引。这非常快——每六十秒进行一次是完全合理的。构建索引后,将其同步到另一个S3存储桶。

  • 有一个运行nginx(配置如下)的Web服务器(或一组位于负载均衡器后面的Web服务器),源为第二个S3存储桶。

生成静态文件

首先,在某个地方安装dumb-pypi(例如,安装到虚拟环境)。

按照设计,dumb-pypi在构建索引时不需要您提供软件包。您只需要一个文件名列表,每行一个。例如

dumb-init-1.1.2.tar.gz
dumb_init-1.2.0-py2.py3-none-manylinux1_x86_64.whl
ocflib-2016.10.31.0.40-py2.py3-none-any.whl
pre_commit-0.9.2.tar.gz

您还应该知道一个用于访问这些软件包的URL(如果您从与索引相同的宿主提供它们,它可以是相对URL)。例如,它可能是https://my-pypi-packages.s3.amazonaws.com/../../pool/

然后您可以调用脚本

$ dumb-pypi \
    --package-list my-packages \
    --packages-url https://my-pypi-packages.s3.amazonaws.com/ \
    --output-dir my-built-index

构建的索引将位于my-built-index。现在您需要决定如何用Web服务器(nginx是一个不错的选择——详情见下文!)来提供它。

软件包的附加选项

您可以通过向dumb-pypi提供软件包列表的扩展JSON输入语法来扩展您注册表的功能。不要使用上面列出的每行一个文件名的格式,而是将文件格式化为每行一个JSON对象,如下所示

{"filename": "dumb-init-1.1.2.tar.gz", "hash": "md5=<hash>", "requires_dist": ["cfgv"], "requires_python": ">=3.6", "uploaded_by": "ckuehl", "upload_timestamp": 1512539924}

filename键是必需的。所有其他键都是可选的,并将用于在生成的存储库中提供附加信息。这些扩展信息可以用于确定,例如,谁上传了软件包。(大多数此类信息对人类用户在Web UI中很有用,而不是对pip。)

您从哪里获取有关哈希、上传者等信息?这由您决定——dumb-pypi不涉及存储或计算这些数据。如果您使用S3,一个简单的选项是在上传时将其存储为S3元数据

部分重建支持

如果您想避免不断重建整个注册表,则可以将--previous-package-list(或--previous-package-list-json)参数传递给dumb-pypi,指向上次调用dumb-pypi时使用的列表。只有与更改的软件包相关的文件将重新构建,这可以为您节省时间和不必要的I/O。

上一个软件包列表JSON在输出中可用为packages.json

推荐的nginx配置

您可以从任何静态Web服务器提供软件包(包括直接从S3),但为了与旧版本的pip兼容,需要进行一点URL重写(有关各种pip版本行为的完整详情,请参阅RATIONALE.md)。

特别是,如果您想支持旧版本的pip(8.1.2之前的版本),则需要将此逻辑应用于软件包名称(来自PEP 503

def normalize(name):
    return re.sub(r'[-_.]+', '-', name).lower()

以下是一个示例nginx配置,它支持所有版本的pip和easy_install

server {
    location / {
        root /path/to/index;
        set_by_lua $canonical_uri "return string.gsub(string.lower(ngx.var.uri), '[-_.]+', '-')";
        try_files $uri $uri/index.html $canonical_uri $canonical_uri/index.html =404;
    }
}

如果您不关心easy_install或8.1.2之前的pip版本,可以省略canonical_uri技巧。

使用pip与已部署的索引服务器

运行pip时,请传递参数-i https://my-pypi-server/simple或设置环境变量PIP_INDEX_URL=https://my-pypi-server/simple

与公共PyPI的已知不兼容性

我们试图保持与标准PyPI接口的兼容性,但由于dumb-pypi的设计,目前存在一些难以修复的不兼容性

  • 尽管支持JSON API端点,但许多JSON API中的键不存在,因为它们需要检查包,而dumb-pypi无法执行此操作。其中一些,如requires_pythonrequires_dist,可以作为JSON传递。

  • 按版本JSON API端点仅包括关于当前请求版本的 数据,而不是所有版本,与公共PyPI不同。换句话说,如果您访问/pypi/<package>/1.0.0/json,您将只能在releases键下看到1.0.0版本,而不是所有已发布的版本。常规非版本化API路由(/pypi/<package>/json)将包含所有版本。

贡献

感谢您的贡献!要开始,请运行make venv,然后运行. venv/bin/activate来加载虚拟环境。现在您应该在您的路径上有一个使用您的代码签出版本的dumb-pypi命令。

要运行测试,请调用make test。要运行单个测试,可以在激活虚拟环境后执行pytest -k name_of_test tests(使用虚拟环境)。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

dumbr_pypi-1.13.0.tar.gz (17.2 kB 查看哈希值)

上传时间

构建分布

dumbr_pypi-1.13.0-py2.py3-none-any.whl (16.0 kB 查看哈希值)

上传时间 Python 2 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面