一个用于与pip/easy_install一起使用的最小PyPI服务器。
项目描述
pypiserver - 与pip/easy_install一起使用的最小PyPI服务器
名称 | 描述 |
---|---|
版本 | 2.2.0 |
日期 | 2024-09-15 |
来源 | https://github.com/pypiserver/pypiserver |
PyPI | https://pypi.ac.cn/project/pypiserver/ |
测试 | https://github.com/pypiserver/pypiserver/actions |
维护者 | @ankostis , @mplanchard , @dee-me-tree-or-love , @pawamoy , 新成员? 我们欢迎新的维护者! #397 |
许可证 | zlib/libpng + MIT |
社区 | https://pypiserver.zulipchat.com |
pypiserver 是一个与 PyPI 兼容的最小服务器,适用于 pip 或 easy_install。它基于 bottle,并从常规目录中提供软件包。可以使用 pip、setuptools、twine、pypi-uploader 或简单地使用 scp 来上传Wheels、bdists、eggs及其相应的PGP签名。
[!Note] 推动官方 PyPI 的软件是 Warehouse。然而,Warehouse 是相当专业化的,专门用于 pypi.org 的软件,不应在其他上下文中使用。特别是,它不支持作为自定义包索引供用户自己提供软件包。
pypiserver 实现了与 PyPI 相同的接口,允许标准 Python 打包工具,如 pip 和 twine,将其作为包索引与之交互,就像它们与 PyPI 交互一样,同时使得运行索引服务器变得更加容易。
pypiserver
目录
- pypiserver - 与pip/easy_install一起使用的最小PyPI服务器
- pypiserver
- 许可
快速入门:安装和使用
pypiserver 与 Python 3.6+ 和 PyPy3 兼容。
较旧的Python版本可能仍然可以使用,但未经过测试。
对于旧版Python,请使用 pypiserver-1.x 系列。请注意,这些不受官方支持,并且不会收到错误修复或新功能。
[!TIP]
以下命令在具有posix shell的类Unix操作系统上运行。字符 '~' 展开为用户的家目录。
如果您使用的是Windows操作系统,您将需要使用他们的“Windows兼容版本”。本文档中的其余部分也是如此。
-
使用以下命令安装 pypiserver
pip install pypiserver # Or: pypiserver[passlib,cache] mkdir ~/packages # Copy packages into this directory.
[!TIP] 请参阅 替代安装方法
-
将一些包复制到您的 ~/packages 文件夹,然后启动并运行 pypiserver
pypi-server run -p 8080 ~/packages & # Will listen to all IPs.
-
从客户端计算机,输入以下内容
# Download and install hosted packages. pip install --extra-index-url http://localhost:8080/simple/ ... # or pip install --extra-index-url http://localhost:8080 ... # Search hosted packages. pip search --index http://localhost:8080 ... # Note that pip search does not currently work with the /simple/ endpoint.
[!TIP] 请参阅 客户端配置 以避免繁琐的输入。
-
在cmd行中输入 pypi-server -h 来打印详细的用法信息
usage: pypi-server [-h] [-v] [--log-file FILE] [--log-stream STREAM] [--log-frmt FORMAT] [--hash-algo HASH_ALGO] [--backend {auto,simple-dir,cached-dir}] [--version] {run,update} ... start PyPI compatible package server serving packages from PACKAGES_DIRECTORY. If PACKAGES_DIRECTORY is not given on the command line, it uses the default ~/packages. pypiserver scans this directory recursively for packages. It skips packages and directories starting with a dot. Multiple package directories may be specified. positional arguments: {run,update} run Run pypiserver, serving packages from PACKAGES_DIRECTORY update Handle updates of packages managed by pypiserver. By default, a pip command to update the packages is printed to stdout for introspection or pipelining. See the `-x` option for updating packages directly. optional arguments: -h, --help show this help message and exit -v, --verbose Enable verbose logging; repeat for more verbosity. --log-file FILE Write logging info into this FILE, as well as to stdout or stderr, if configured. --log-stream STREAM Log messages to the specified STREAM. Valid values are stdout, stderr, and none --log-frmt FORMAT The logging format-string. (see `logging.LogRecord` class from standard python library) --hash-algo HASH_ALGO Any `hashlib` available algorithm to use for generating fragments on package links. Can be disabled with one of (0, no, off, false). --backend {auto,simple-dir,cached-dir} A backend implementation. Keep the default 'auto' to automatically determine whether to activate caching or not --version show program's version number and exit Visit https://github.com/pypiserver/pypiserver for more information
关于pypi服务器运行的更多详细信息
在cmd行中输入 pypi-server run -h 来打印详细的用法信息
usage: pypi-server run [-h] [-v] [--log-file FILE] [--log-stream STREAM]
[--log-frmt FORMAT] [--hash-algo HASH_ALGO]
[--backend {auto,simple-dir,cached-dir}] [--version]
[-p PORT] [-i HOST] [-a AUTHENTICATE]
[-P PASSWORD_FILE] [--disable-fallback]
[--fallback-url FALLBACK_URL]
[--health-endpoint HEALTH_ENDPOINT] [--server METHOD]
[-o] [--welcome HTML_FILE] [--cache-control AGE]
[--log-req-frmt FORMAT] [--log-res-frmt FORMAT]
[--log-err-frmt FORMAT]
[package_directory [package_directory ...]]
positional arguments:
package_directory The directory from which to serve packages.
optional arguments:
-h, --help show this help message and exit
-v, --verbose Enable verbose logging; repeat for more verbosity.
--log-file FILE Write logging info into this FILE, as well as to
stdout or stderr, if configured.
--log-stream STREAM Log messages to the specified STREAM. Valid values are
stdout, stderr, and none
--log-frmt FORMAT The logging format-string. (see `logging.LogRecord`
class from standard python library)
--hash-algo HASH_ALGO
Any `hashlib` available algorithm to use for
generating fragments on package links. Can be disabled
with one of (0, no, off, false).
--backend {auto,simple-dir,cached-dir}
A backend implementation. Keep the default 'auto' to
automatically determine whether to activate caching or
not
--version show program's version number and exit
-p PORT, --port PORT Listen on port PORT (default: 8080)
-i HOST, -H HOST, --interface HOST, --host HOST
Listen on interface INTERFACE (default: 0.0.0.0)
-a AUTHENTICATE, --authenticate AUTHENTICATE
Comma-separated list of (case-insensitive) actions to
authenticate (options: download, list, update;
default: update).
Any actions not specified are not authenticated, so
to authenticate downloads and updates, but allow
unauthenticated viewing of the package list, you would
use:
pypi-server -a 'download, update' -P
./my_passwords.htaccess
To disable authentication, use:
pypi-server -a . -P .
See the `-P` option for configuring users and
passwords.
Note that when uploads are not protected, the
`register` command is not necessary, but `~/.pypirc`
still needs username and password fields, even if
bogus.
-P PASSWORD_FILE, --passwords PASSWORD_FILE
Use an apache htpasswd file PASSWORD_FILE to set
usernames and passwords for authentication.
To allow unauthorized access, use:
pypi-server -a . -P .
--disable-fallback Disable the default redirect to PyPI for packages not
found in the local index.
--fallback-url FALLBACK_URL
Redirect to FALLBACK_URL for packages not found in the
local index.
--health-endpoint HEALTH_ENDPOINT
Configure a custom liveness endpoint. It always
returns 200 Ok if the service is up. Otherwise, it
means that the service is not responsive.
--server METHOD Use METHOD to run the server. Valid values include
paste, cherrypy, twisted, gunicorn, gevent, wsgiref,
and auto. The default is to use "auto", which chooses
one of paste, cherrypy, twisted, or wsgiref.
-o, --overwrite Allow overwriting existing package files during
upload.
--welcome HTML_FILE Use the contents of HTML_FILE as a custom welcome
message on the home page.
--cache-control AGE Add "Cache-Control: max-age=AGE" header to package
downloads. Pip 6+ requires this for caching.AGE is
specified in seconds.
--log-req-frmt FORMAT
A format-string selecting Http-Request properties to
log; set to '%s' to see them all.
--log-res-frmt FORMAT
A format-string selecting Http-Response properties to
log; set to '%s' to see them all.
--log-err-frmt FORMAT
A format-string selecting Http-Error properties to
log; set to '%s' to see them all.
关于pypi-server更新的更多详细信息
关于 pypi-server update 的更多详细信息
usage: pypi-server update [-h] [-v] [--log-file FILE] [--log-stream STREAM]
[--log-frmt FORMAT] [--hash-algo HASH_ALGO]
[--backend {auto,simple-dir,cached-dir}] [--version]
[-x] [-d DOWNLOAD_DIRECTORY] [-u]
[--blacklist-file IGNORELIST_FILE]
[package_directory [package_directory ...]]
positional arguments:
package_directory The directory from which to serve packages.
optional arguments:
-h, --help show this help message and exit
-v, --verbose Enable verbose logging; repeat for more verbosity.
--log-file FILE Write logging info into this FILE, as well as to
stdout or stderr, if configured.
--log-stream STREAM Log messages to the specified STREAM. Valid values are
stdout, stderr, and none
--log-frmt FORMAT The logging format-string. (see `logging.LogRecord`
class from standard python library)
--hash-algo HASH_ALGO
Any `hashlib` available algorithm to use for
generating fragments on package links. Can be disabled
with one of (0, no, off, false).
--backend {auto,simple-dir,cached-dir}
A backend implementation. Keep the default 'auto' to
automatically determine whether to activate caching or
not
--version show program's version number and exit
-x, --execute Execute the pip commands rather than printing to
stdout
-d DOWNLOAD_DIRECTORY, --download-directory DOWNLOAD_DIRECTORY
Specify a directory where packages updates will be
downloaded. The default behavior is to use the
directory which contains the package being updated.
-u, --allow-unstable Allow updating to unstable versions (alpha, beta, rc,
dev, etc.)
--blacklist-file IGNORELIST_FILE, --ignorelist-file IGNORELIST_FILE
Don't update packages listed in this file (one package
name per line, without versions, '#' comments
honored). This can be useful if you upload private
packages into pypiserver, but also keep a mirror of
public packages that you regularly update. Attempting
to pull an update of a private package from `pypi.org`
might pose a security risk - e.g. a malicious user
might publish a higher version of the private package,
containing arbitrary code.
客户端配置
始终在命令行中指定pypi URL有些繁琐。由于 pypiserver 在没有请求的包时将 pip/easy_install 重定向到 pypi.org 索引,因此将其配置为始终使用您本地的pypi索引是一个好主意。
配置pip
对于 pip 命令,您可以通过设置环境变量 PIP_EXTRA_INDEX_URL 在您的 .bashr/.profile/.zshrc 中来完成
export PIP_EXTRA_INDEX_URL=http://localhost:8080/simple/
或者通过添加以下行到 ~/.pip/pip.conf
[global]
extra-index-url = http://localhost:8080/simple/
[!NOTE]
如果您在没有 https 的远程URL上安装了 pypiserver,您将收到来自 pip 的“不受信任”警告,敦促您添加 --trusted-host 选项。您也可以将此选项永久添加到您的配置文件或环境变量中。
配置easy_install
对于 easy_install 命令,您可以在 ~/.pydistutils.cfg 中设置以下配置
[easy_install]
index_url = http://localhost:8080/simple/
远程上传软件包
您可以直接将包复制到服务器的文件夹中(例如,使用 scp),也可以使用Python工具来完成这项任务,例如 python setup.py upload。在这种情况下,pypiserver 负责验证上传请求。
[!NOTE]
我们强烈建议对上传进行 密码保护!
您可以选择禁用上传的认证(例如,在内部网络中)。为了避免草率的保安决定,请阅读有关 -P 和 -a 选项的帮助。
Apache样认证(htpasswd)
-
首先确保您已安装了 passlib 模块(请注意,需要 passlib>=1.6),这是解析由 -P,--passwords 选项指定的 Apache htpasswd 文件所需的,见以下步骤。
pip install passlib
-
使用以下命令创建 Apache htpasswd 文件,至少包含一个用户/密码对(您将需要输入密码)
htpasswd -sc htpasswd.txt <some_username>
[!TIP]
阅读此 SO 问题,了解在 Windows 下运行
htpasswd
命令或如果您对内部服务的密码不关心(从保安角度看仍然是“不好”)的密码无效时,您可以使用此 公共服务
[!TIP]
通过API访问 pypiserver 时,可以通过 auther 配置标志提供替代认证方法。任何返回布尔值的可调用对象都可以传递给 pypiserver 配置,以提供自定义认证。例如,要配置 pypiserver 使用 python-pam
import pam pypiserver.default_config(auther=pam.authenticate)
请参阅 使用临时代理认证提供程序
获取更多信息。
-
您只需要重新启动服务器一次带有 -P 选项(但稍后可以动态添加或更新用户/密码对)
./pypi-server run -p 8080 -P htpasswd.txt ~/packages &
使用setuptools上传
-
在客户端,编辑或创建一个包含类似内容的 ~/.pypirc 文件
[distutils] index-servers = pypi local [pypi] username:<your_pypi_username> password:<your_pypi_passwd> [local] repository: http://localhost:8080 username: <some_username> password: <some_passwd>
-
然后从您希望上传的 Python 项目的目录中,运行以下命令
python setup.py sdist upload -r local
使用twine上传
为了避免将您的密码以明文形式存储在磁盘上,您可以选择以下方法之一
-
使用带有 -r 选项的 register setuptools 的命令,如下所示
python setup.py sdist register -r local upload -r local
-
使用 twine 库,它将过程分为两个步骤。此外,它支持使用 PGP-Signatures 签名您的文件,并将生成的 .asc 文件上传到 pypiserver:
twine upload -r local --sign -identity user_name ./foo-1.zip
使用Docker镜像
从版本1.2.5开始,每次向master、每个dev、alpha或beta发布以及每个最终发布推送都会构建官方的Docker镜像。最新完整发布版本始终可以在标签latest下找到,而当前master分支始终可以在标签unstable下找到。
您可以在我们的Docker仓库查看当前可用的所有标签。
要使用Docker运行最新版本的pypiserver,只需
docker run pypiserver/pypiserver:latest run
这将在容器内启动从/data/packages目录服务软件包的pypiserver,监听容器端口8080。
容器接受与正常pypi-server可执行文件相同的所有参数,除了内部容器端口(-p),它始终为8080。
当然,仅仅运行容器并不那么有趣。要将主机上的端口80映射到容器的端口8080:
docker run -p 80:8080 pypiserver/pypiserver:latest run
您现在可以在网页浏览器中通过localhost:80访问您的pypiserver。
要从主机上的目录(例如,~/packages)提供服务包:
docker run -p 80:8080 -v ~/packages:/data/packages pypiserver/pypiserver:latest run
要针对本地.htpasswd文件进行身份验证:
docker run -p 80:8080 -v ~/.htpasswd:/data/.htpasswd pypiserver/pypiserver:latest run -P .htpasswd packages
您还可以指定使用Docker服务运行pypiserver,使用composefile。一个示例composefile提供如下
替代安装方法
在尝试以下方法之前,首先使用以下命令检查是否已存在pypiserver的先前版本,并(可选)卸载它们:
# VERSION-CHECK: Fails if not installed.
pypi-server --version
# UNINSTALL: Invoke again until it fails.
pip uninstall pypiserver
安装最新版本
如果pypi中的最新版本是预发布版本,您必须使用pip的--pre选项。要更新现有安装,请结合使用--ignore-installed
pip install pypiserver --pre -I
假设您在PATH上已安装git,您可以直接使用以下命令从github安装最新的pypiserver:
pip install git+git://github.com/pypiserver/pypiserver.git
配方
管理包目录
pypi-server命令有update命令,可以搜索可用软件包的更新。它扫描软件包目录以查找可用软件包,并在pypi.org上搜索更新。如果没有进一步选项,pypi-server update将只打印必须运行的命令列表,以获取每个软件包的最新版本。输出如下
$ ./pypi-server update
checking 106 packages for newer version
.........u.e...........e..u.............
.....e..............................e...
..........................
no releases found on pypi for PyXML, Pymacs, mercurial, setuptools
# update raven from 1.4.3 to 1.4.4
pip -q install --no-deps --extra-index-url https://pypi.ac.cn/simple/ -d /home/ralf/packages/mirror raven==1.4.4
# update greenlet from 0.3.3 to 0.3.4
pip -q install --no-deps --extra-index-url https://pypi.ac.cn/simple/ -d /home/ralf/packages/mirror greenlet==0.3.4
它首先打印出每个软件包在pypi上检查到的可用版本后的单个字符。点(.)表示软件包是最新的,'u'表示软件包可以更新,'e'表示pypi上的发布列表为空。之后,它显示一个可以用于更新单个软件包的pip命令行。要么复制粘贴该命令,要么运行pypi-server update -x来真正执行这些命令。但是,您需要安装pip才能使这生效。
指定附加的-u选项也将允许下载alpha、beta和发布候选版本。如果没有此选项,则不会考虑这些版本。
提供数千个软件包
[!IMPORTANT] 默认情况下,pypiserver在每次发生传入HTTP请求时都会扫描整个软件包目录。对于少量软件包来说这没问题,但当服务数千个软件包时,会导致明显的速度减慢。
如果您遇到这个问题,可以通过启用pypiserver的目录缓存功能来获得显著的加速。唯一的要求是安装watchdog软件包,或者可以在安装pypiserver时安装,通过指定cache额外选项:
pip install pypiserver[cache]
通过使用您的Web服务器内建的缓存功能可以获得额外的加速。例如,如果您正在使用以下Behind a reverse proxy
中描述的nginx
作为反向代理,您可以轻松启用缓存。例如,要允许nginx缓存最多10GB数据,最多1小时:
proxy_cache_path /data/nginx/cache
levels=1:2
keys_zone=pypiserver_cache:10m
max_size=10g
inactive=60m
use_temp_path=off;
server {
# ...
location / {
proxy_cache pypiserver_cache;
proxy_pass http://localhost:8080;
}
}
[!TIP] 使用Web服务器缓存特别有助于您有高请求量。使用nginx缓存,一个实际的pypiserver安装能够轻松支持在高峰负载时每分钟超过1000个软件包的下载。
管理自动化启动
在系统启动时自动启动pypiserver有多种选择。其中两种最常见的是Linux系统的systemd和supervisor。对于Windows系统,如果没有第三方工具如NSSM,创建服务并不是一件容易的事情。
作为systemd服务运行
systemd是大多数现代Linux系统默认安装的,因此它是一个管理pypiserver进程的优秀选项。以下是一个systemd的示例配置文件:
[Unit]
Description=A minimal PyPI server for use with pip/easy_install.
After=network.target
[Service]
Type=simple
# systemd requires absolute path here too.
PIDFile=/var/run/pypiserver.pid
User=www-data
Group=www-data
ExecStart=/usr/local/bin/pypi-server run -p 8080 -a update,download --log-file /var/log/pypiserver.log -P /etc/nginx/.htpasswd /var/www/pypi
ExecStop=/bin/kill -TERM $MAINPID
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
WorkingDirectory=/var/www/pypi
TimeoutStartSec=3
RestartSec=5
[Install]
WantedBy=multi-user.target
调整路径并将此文件作为pypiserver.service添加到您的systemd/system目录中,将允许您使用systemctl管理pypiserver进程,例如systemctl start pypiserver。
更多关于systemd的有用信息可以在以下网址找到:https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
通过supervisor启动
supervisor的优点是它是一个纯Python包,因此它为进程管理提供了出色的跨平台支持。以下是一个supervisor的示例配置文件:
[program:pypi]
command=/home/pypi/pypi-venv/bin/pypi-server run -p 7001 -P /home/pypi/.htpasswd /home/pypi/packages
directory=/home/pypi
user=pypi
autostart=true
autorestart=true
stderr_logfile=/var/log/pypiserver.err.log
stdout_logfile=/var/log/pypiserver.out.log
然后,可以通过supervisord使用supervisorctl来管理进程。
使用NSSM作为服务运行
对于Windows,从https://nssm.cc下载NSSM,解压到如Program Files等期望的位置。决定您要使用win32
还是win64
,并将该exe
添加到环境变量PATH
中。
创建一个start_pypiserver.bat文件
pypi-server run -p 8080 C:\Path\To\Packages &
[!TIP] 在创建服务之前先运行批处理文件进行测试。确保您可以远程访问服务器并安装包。如果可以,请继续,如果不能,请调试直到您可以为止。这将确保在将NSSM添加到混合之前,您知道服务器正在运行。
从命令提示符
nssm install pypiserver
此命令将启动一个NSSM图形界面应用程序
Path: C:\Path\To\start_pypiserver.bat
Startup directory: Auto generates when selecting path
Service name: pypiserver
还有更多标签,但这只是一个基本设置。如果服务需要以特定的登录凭据运行,请确保在登录标签中输入这些凭据。
启动服务
nssm start pypiserver
[!TIP] 其他有用的命令
nssm --help nssm stop <servicename> nssm restart <servicename> nssm status <servicename>有关详细信息,请访问https://nssm.cc
使用不同的WSGI服务器
-
bottle web服务器支持许多WSGI服务器,包括paste、cherrypy、twisted和wsgiref(Python的一部分);您可以通过使用--server标志来选择它们。
-
您可以使用以下交互式代码查看所有支持的WSGI服务器:
>>> from pypiserver import bottle >>> list(bottle.server_names.keys()) ['cgi', 'gunicorn', 'cherrypy', 'eventlet', 'tornado', 'geventSocketIO', 'rocket', 'diesel', 'twisted', 'wsgiref', 'fapws3', 'bjoern', 'gevent', 'meinheld', 'auto', 'aiohttp', 'flup', 'gae', 'paste', 'waitress']
-
如果上述任何服务器都不符合您的需求,只需调用pypiserver:app()方法,该方法返回内部WSGI应用程序(不启动服务器) - 您可以将其发送到任何您喜欢的WSGI服务器。请参阅利用API部分。
-
以下是一些示例 - 您可以在bottle网站中找到更多详细信息。
Apache
要使用您的Apache2与pypiserver,最好使用mod_wsgi,如bottle文档中所述。
[!NOTE] 如果您选择使用mod_proxy,请注意,您可能会遇到前缀路径的问题(见#155)。
-
根据需要将以下Apache配置文件放置在顶层作用域内,或放在某个
<VirtualHost>
内部(由Thomas Waldmann贡献):WSGIScriptAlias / /yoursite/wsgi/pypiserver-wsgi.py WSGIDaemonProcess pypisrv user=pypisrv group=pypisrv umask=0007 \ processes=1 threads=5 maximum-requests=500 \ display-name=wsgi-pypisrv inactivity-timeout=300 WSGIProcessGroup pypisrv WSGIPassAuthorization On # Required for authentication (https://github.com/pypiserver/pypiserver/issues/288) <Directory /yoursite/wsgi > Require all granted </Directory>
或者,如果使用较旧的Apache < 2.4,将最后一部分替换为以下内容:
<Directory /yoursite/wsgi > Order deny,allow Allow from all </Directory>
-
然后创建/yoursite/cfg/pypiserver.wsgi文件,并确保WSGIDaemonProcess指令(例如示例中的pypisrv:pypisrv)的user和group对该文件有读取权限。
import pypiserver conf = pypiserver.default_config( root = "/yoursite/packages", password_file = "/yoursite/htpasswd", ) application = pypiserver.app(**conf)
[!提示] 如果您在虚拟环境中安装了 pypiserver,请遵循 mod_wsgi 的说明,并在上面的 Python 代码前面添加以下内容
import site site.addsitedir('/yoursite/venv/lib/pythonX.X/site-packages')
[!注意] 由于安全原因,请注意 Directory 指令仅授予对包含 wsgi 启动脚本的目录的访问权限;没有其他权限。
[!注意] 要在 Apache 上启用 HTTPS 支持,请配置包含 WSGI 配置的指令以使用 SSL。
gunicorn
以下命令使用 gunicorn 启动 pypiserver
gunicorn -w4 'pypiserver:app(root="/home/ralf/packages")'
或者当使用多个根目录时
gunicorn -w4 'pypiserver:app(root=["/home/ralf/packages", "/home/ralf/experimental"])'
paste
paste 允许在不同的 URL 路径下运行多个 WSGI 应用程序。因此,可以在不同的路径上提供不同的软件包集。
以下示例 paste.ini 可以用于在不同的路径上提供稳定和不稳定的软件包
[composite:main]
use = egg:Paste#urlmap
/unstable/ = unstable
/ = stable
[app:stable]
use = egg:pypiserver#main
root = ~/stable-packages
[app:unstable]
use = egg:pypiserver#main
root = ~/stable-packages
~/unstable-packages
[server:main]
use = egg:gunicorn#main
host = 0.0.0.0
port = 9000
workers = 5
accesslog = -
[!注意] 为了使此功能正常工作,您需要安装一些额外的依赖项,例如:
pip install paste pastedeploy gunicorn pypiserver然后服务器可以启动
gunicorn_paster paste.ini
在反向代理后面
您还可以在反向代理后面运行 pypiserver。
Nginx
扩展您的 nginx 配置
upstream pypi {
server pypiserver.example.com:12345 fail_timeout=0;
}
server {
server_name myproxy.example.com;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://pypi;
}
}
从 pypiserver 1.3 版本开始,您还可以在反向代理配置中使用 X-Forwarded-Host
标头以启用更改基本 URL。例如,如果您想在服务器上的特定路径下托管 pypiserver
upstream pypi {
server localhost:8000;
}
server {
location /pypi/ {
proxy_set_header X-Forwarded-Host $host:$server_port/pypi;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://pypi;
}
}
支持HTTPS
使用反向代理是将 pypiserver 放在 HTTPS 后面的首选方法。例如,要使用 nginx
在端口 443 上将 pypiserver 放在 HTTPS 后面,并自动进行 HTTP 重定向
upstream pypi {
server localhost:8000;
}
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name pypiserver.example.com;
ssl_certificate /etc/star.example.com.crt;
ssl_certificate_key /etc/star.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://pypi;
}
}
[!提示] 请参阅 nginx 的 HTTPS 文档 以获取更多详细信息。
使用,例如,certbot 和 letsencrypt 可以简化获取和保持证书更新的过程。
Traefik
您还可以使用 Traefik 将 pypiserver 放在 HTTPS 端口 443 后面,并使用 Docker Compose 自动进行 HTTP 重定向。有关更多信息,请参阅提供的docker-compose.yml 示例。
利用API
为了启用临时的认证提供程序或使用 bottle 不直接支持的 WSGI 服务器,您需要通过其 API 启动 pypiserver。
-
配置 pypiserver 的主要入口点是 pypiserver:app() 函数。此函数返回内部 WSGI 应用程序,然后您可以将它发送到您喜欢的任何 WSGI 服务器。
-
要获取所有 pypiserver:app() 关键字及其说明,请阅读 pypiserver:default_config() 函数。
-
最后,要启动配置的应用程序,请调用 bottle:run(app, host, port, server) 函数。请注意,pypiserver 随附有其自己的 bottle 版本;要使用它,请按如下方式导入:from pypiserver import bottle
使用临时的认证提供者
只能使用 API 设置 pypiserver:app() 函数的 auther 关键字。这可以是任何在传递 username 和 password 给它时返回布尔值的可调用对象。
例如,要基于 Unix 下的 /etc/passwd 文件进行用户认证,您可以通过以下步骤将这些决策委托给 python-pam 库
-
确保安装了 python-pam 模块
pip install python-pam
-
创建一个符合以下模式的 Python 脚本
$ cat > pypiserver-start.py import pypiserver from pypiserver import bottle import pam app = pypiserver.app(root='./packages', auther=pam.authenticate) bottle.run(app=app, host='0.0.0.0', port=80, server='auto') [Ctrl+ D]
-
调用 Python 脚本来启动 pypiserver
python pypiserver-start.py
[注意] python-pam 模块需要读取 /etc/shadow 文件;您可以添加 pypiserver 运行的用户到 shadow 用户组,使用以下命令: sudo usermod -a -G shadow pypy-user。
与MicroPython一起使用
MicroPython 解释器可以为嵌入式设备安装包,使用模块 upip.py。此模块使用专用的 json-endpoint 来检索包信息。此端点由 pypiserver 支持。
可以使用 micropython 的 UNIX 端口进行测试
cd micropython
ports/unix/micropython -m tools.upip install -i http://my-server:8080 -p /tmp/mymodules micropython-foobar
从嵌入式设备的 REPL 安装包的方式如下
import network
import upip
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect('<your ESSID>', '<your password>')
upip.index_urls = ["http://my-server:8080"]
upip.install("micropython-foobar")
关于 micropython 打包的更多信息,请参阅此处: https://docs.micropython.org/en/latest/reference/packages.html
自定义健康检查端点
pypiserver 在 /health 提供默认的健康端点。如果服务正常运行,它总是返回 200 Ok。否则,表示该服务无响应。
此外,pypiserver 允许用户自定义健康端点。允许使用字母数字字符、连字符、正斜杠和下划线,且端点不应与任何现有路由重叠。有效示例:/healthz,/health/live-1,/api_health,/action/health
通过CLI参数配置自定义健康端点
使用 --health-endpoint 参数运行 pypiserver
pypi-server run --health-endpoint /action/health
通过脚本配置自定义健康端点
import pypiserver
from pypiserver import bottle
app = pypiserver.app(root="./packages", health_endpoint="/action/health")
bottle.run(app=app, host="0.0.0.0", port=8080, server="auto")
尝试 curl http://localhost:8080/action/health
来源
要创建仓库的副本,使用
git clone https://github.com/pypiserver/pypiserver.git
cd pypiserver
要接收上述文件夹中的任何后续更改,使用
git pull
已知限制
[重要] pypiserver 并未实现如 PyPI 所见到的完整 API。它仅实现了使 easy_install、pip install 和 搜索 工作所需的最小功能。
以下为已知的限制
- 比较上传的包和 pypi 以查看是否过时的 pypi -U 命令不尊重 http-proxy 环境变量(见 #19)。
- 它接受文档上传,但不将其保存到磁盘(见 #47 中的讨论)。
- 它不处理拼写错误的包,如 pypi-repo 所做的那样,因此建议使用 --extra-index-url 而不是 --index-url(见 #38)。
请使用 Github 的 bugtracker 报告其他发现的错误。
类似项目
有很多其他项目,允许您运行自己的 PyPI 服务器。如果 pypiserver 对您不起作用,以下是最受欢迎的替代方案之一
-
devpi-server:一个可靠的快速 pypi.org 缓存服务器,是完整的 github-style pypi 索引服务器和打包元工具 的一部分。(版本:2.1.4,访问日期:2015年8月3日)
-
检查这个 SO 问题: 如何创建自己的 pypi
未维护或存档
这些项目曾是 pypiserver 的替代方案,但现在它们要么不再维护,要么已存档。
-
pip2pi:一个简单的命令行工具,它从 pip 要求构建一个兼容 PyPI 的本地文件夹
-
flask-pypi-proxy:一个 PyPI 代理,同时允许上传自定义包
相关软件
以下列出了一些与 pypiserver 作为索引服务器使用直接相关的软件项目,您可能希望熟悉它们
-
pypi-uploader:一个命令行工具,用于从 PyPI 上传包到您的 pypiserver,而无需首先在本地存储它们。
-
twine:一个命令行工具,用于与 PyPI 或 pypiserver 交互。
许可
PyPI服务器 包含一个 MIT 许可下的 bottle 的副本,其余部分采用 zlib/libpng 许可证分发。请参阅 LICENSE.txt 文件。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪一个,请了解有关 安装包 的更多信息。