这个概念证明展示了如何在不使用virtualenv的情况下使用python包
项目描述
概念证明:Monotrail
这个概念证明展示了如何在不使用virtualenv的情况下使用python包。它将安装python本身和你的依赖项,前提是在目录中有一个requirement.txt
或pyproject.toml
/poetry.lock
。可以使用pipx、pip或从发布或主分支的二进制文件进行安装。
pipx install monotrail # or `pip install monotrail`
monotrail run python my_script.py
每个依赖项只全局安装一次,并连接到你的代码。没有venv目录,没有明确安装,没有激活,没有pyenv。
这是一个概念证明,因此只有大多数功能缺失,可能会崩溃或产生无意义的结果。例如,非Linux系统测试不佳,安装不便,错误消息不佳,只支持PyPI,启动缓慢,只支持某些requirement.txt语法,交互模式下的lockfiles不保存,某些pkg_resources使用不起作用等。
monotrail意味着向你展示可以在不使用传统的“在环境中安装包”的情况下使用python。它还集成了python-build-standalone,因此你不再需要安装python。
它包括pipx和tox的简单实现。还有一个针对notebooks的pip包,其中可以在运行时交互式添加包,为每个notebook获取独立的包集,并避免版本冲突。
用法
首先下载二进制文件并将其放入PATH中(例如,通过.local/bin
)
wget -O ~/.local/bin/monotrail https://konstin.github.io/poc-monotrail/main/ubuntu/monotrail
chmod +x ~/.local/bin/monotrail
确保你有一个requirements.txt
或pyproject.toml
/poetry.lock
monotrail run python my_script.py
选择python版本和额外功能
monotrail run -p 3.9 --extras fancy-pants python my_script.py --some-option
运行之前在.venv/bin
中的命令
monotrail run command pytest
还有一个具有入口点的python包
pip install monotrail
monotrail_python path/to/your/script.py
与jupyter notebooks一起使用
!pip install monotrail
import monotrail
monotrail.interactive(
numpy="^1.21",
pandas="^1"
)
在google colab中,你可能想要导入你的git仓库
import monotrail
monotrail.from_git(
"https://github.com/sokrypton/ColabFold", "63b42b8f5b5da418efecf6c4d11490a96595020d"
)
作为pipx的替代品
monotrail ppipx --extras jupyter black .
作为tox的替代品
monotrail run -p 3.8 -p 3.9 -p 3.10 command pytest
你可以将monotrail
链接到名为python
、python3
或python3.x
的文件,它将作为python3.8或指定的python版本运行。
还有一个扁平源布局的演示,其中你可以在src中直接放置__init__.py
,而不是在src/srcery/__init__.py
中嵌套。
srcery
├── poetry.lock
├── pyproject.toml
└── src
├── __init__.py
└── potion.py
设置RUST_LOG=debug
将提供详细信息以跟踪错误。
背景
monotrail 首先解析您想要的 Python 版本(默认为 3.8),如果不存在,则从 PyOxy 下载。它不是作为可执行文件运行 Python,而是加载 libpython.so
并使用 C API。
接下来,我们搜索依赖项列表(poetry.lock
或 requirements.txt
)。如果需要,我们将运行 poetry 解析依赖项(通过为 poetry 本身预先录制的 poetry.lock
进行引导)。我们将所有缺少的包安装到 .cache/monotrail
中的单独目录,并记录所有位置。
我们初始化 Python 并注入一个包含所有内容的自定义 PathFinder,并将其添加到 sys.meta_path
。当 Python 搜索从哪里导入某个内容时,它会通过 sys.meta_path
中的所有 Finder
直到其中一个返回位置。我们的知道从锁定文件中包的位置,Python 看不到其他任何东西,因此您只能从与锁定文件匹配的包中加载。
交互式模式几乎与上面相同,只是我们跳过了 Python 安装,并有一个检查,以确认已导入的包版本没有更改。
基准测试(wheel 安装)
无 venv 安装的便利之处在于我们只安装每个包版本一次,因此不再需要为 pytorch 安装 3 个不同的版本。这需要很少的磁盘空间(即使清理缓存仍然是一个未解决的问题),但更重要的是,这意味着如果之前已使用所有所需的包版本,则“安装”将立即完成。它还消除了重新创建损坏的 venv 的需求。
通过在 Rust 中重新实现 wheel 安装,它也变得更快。 install-wheel-rs
有一个单独的 Python 接口,因此您可以将其作为快速的 wheel 安装程序单独重用。
安装单个大型 wheel(plotly)
$ rm -rf .venv-benchmark && virtualenv .venv-benchmark
$ VIRTUAL_ENV=.venv-benchmark hyperfine -p ".venv-benchmark/bin/pip uninstall -y plotly" \
"target/release/monotrail venv-install test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl" \
".venv-benchmark/bin/pip install --no-deps test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl"
Benchmark #1: target/release/monotrail install test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl
Time (mean ± σ): 5.797 s ± 0.069 s [User: 3.796 s, System: 1.979 s]
Range (min … max): 5.699 s … 5.906 s 10 runs
Benchmark #2: .venv-benchmark/bin/pip install --no-deps test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl
Time (mean ± σ): 7.658 s ± 0.061 s [User: 5.448 s, System: 2.085 s]
Range (min … max): 7.598 s … 7.758 s 10 runs
Summary
'target/release/monotrail install test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl' ran
1.32 ± 0.02 times faster than '.venv-benchmark/bin/pip install --no-deps test-data/popular-wheels/plotly-5.5.0-py2.py3-none-any.whl'
一个数据科学堆栈示例(numpy、pandas、matplotlib)
test-data/poetry/data-science -E tqdm_feature
pip 22.0.4 from /home/konsti/monotrail/.venv-b/lib/python3.8/site-packages/pip (python 3.8)
Poetry version 1.1.13
Benchmark 1: .venv/bin/pip install -q -r requirements-benchmark.txt
Time (mean ± σ): 11.745 s ± 1.159 s [User: 9.637 s, System: 1.339 s]
Range (min … max): 10.830 s … 13.048 s 3 runs
Benchmark 2: poetry install -q --no-root -E tqdm_feature
Time (mean ± σ): 15.039 s ± 0.153 s [User: 41.032 s, System: 5.934 s]
Range (min … max): 14.894 s … 15.199 s 3 runs
Benchmark 3: monotrail poetry-install -E tqdm_feature
Time (mean ± σ): 5.232 s ± 0.135 s [User: 12.850 s, System: 2.334 s]
Range (min … max): 5.089 s … 5.357 s 3 runs
Summary
'monotrail poetry-install -E tqdm_feature' ran
2.24 ± 0.23 times faster than '.venv/bin/pip install -q -r requirements-benchmark.txt'
2.87 ± 0.08 times faster than 'poetry install -q --no-root -E tqdm_feature'
一个中等规模 django 项目
test-data/poetry/mst -E import-json
pip 22.0.4 from /home/konsti/monotrail/.venv-b/lib/python3.8/site-packages/pip (python 3.8)
Poetry version 1.1.13
Benchmark 1: .venv/bin/pip install -q -r requirements-benchmark.txt
Time (mean ± σ): 29.481 s ± 0.186 s [User: 21.001 s, System: 3.313 s]
Range (min … max): 29.331 s … 29.690 s 3 runs
Benchmark 2: poetry install -q --no-root -E import-json
Time (mean ± σ): 70.291 s ± 1.366 s [User: 355.966 s, System: 46.958 s]
Range (min … max): 69.020 s … 71.735 s 3 runs
Benchmark 3: monotrail poetry-install -E import-json
Time (mean ± σ): 10.714 s ± 1.423 s [User: 43.583 s, System: 10.551 s]
Range (min … max): 9.504 s … 12.282 s 3 runs
Summary
'monotrail poetry-install -E import-json' ran
2.75 ± 0.37 times faster than '.venv/bin/pip install -q -r requirements-benchmark.txt'
6.56 ± 0.88 times faster than 'poetry install -q --no-root -E import-json'
启动时间
hello world
$ hyperfine --warmup 2 "python hello.py" "../target/release/monotrail run python hello.py"
Benchmark 1: python hello.py
Time (mean ± σ): 17.3 ms ± 0.8 ms [User: 14.5 ms, System: 2.9 ms]
Range (min … max): 16.3 ms … 20.5 ms 159 runs
Benchmark 2: ../target/release/monotrail run python hello.py
Time (mean ± σ): 218.4 ms ± 5.4 ms [User: 161.6 ms, System: 55.9 ms]
Range (min … max): 212.0 ms … 232.5 ms 13 runs
Summary
'python hello.py' ran
12.65 ± 0.64 times faster than '../target/release/monotrail run python hello.py'
最简单的 numpy 使用方法
import sys
import numpy
print(
f"hi from python {sys.version_info.major}.{sys.version_info.minor} and "
f"numpy {numpy.__version__}"
)
$ hyperfine --warmup 2 "python numpy_version.py" "../target/release/monotrail run python numpy_version.py"
Benchmark 1: python numpy_version.py
Time (mean ± σ): 99.8 ms ± 1.2 ms [User: 127.3 ms, System: 171.7 ms]
Range (min … max): 98.1 ms … 103.1 ms 29 runs
Benchmark 2: ../target/release/monotrail run python numpy_version.py
Time (mean ± σ): 285.9 ms ± 1.8 ms [User: 247.6 ms, System: 169.3 ms]
Range (min … max): 283.4 ms … 289.9 ms 10 runs
Summary
'python numpy_version.py' ran
2.86 ± 0.04 times faster than '../target/release/monotrail run python numpy_version.py'
开发设置
我使用了两个 venv,我激活的 venv 称为 .venv-b
,另一个是用于安装 monotrail 的 .venv
。设置如下
virtualenv .venv-b
. .venv-b/bin/activate
pip install -U maturin[zig] black pip pytest ipython
virtualenv .venv
# pytest runs the tests, jupyter nbconvert is for testing the notebook
.venv/bin/pip install pytest jupyter nbconvert
哈希值 为 monotrail-0.1.0-cp37-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 29e27c8973cac7b81a7fb26c2cb0afa92f510e62385dcd7a7d965676d1d2b158 |
|
MD5 | 665cba38888e6cfbe2b12951ea6c5b0e |
|
BLAKE2b-256 | d2160df005fe4343aa08f6bd1034ec56d2251cc79a530f61f0078c22a5c87636 |
哈希值 为 monotrail-0.1.0-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | c462c59bc59b09f95ca4039afdf182a35401c6e572659d73e692119bbb3c08bb |
|
MD5 | 6c8e7bb8f523fd8cd9d09c5b8aef3366 |
|
BLAKE2b-256 | f822d8bb63f83afe7dfc5d0e73b004d129015acebfa234a61eafcf5f777b7a01 |