跳转到主要内容

一个系统,可以自动处理在编写脚本和简单程序时通常遇到的情况中的 virtualenvs,甚至可以帮助管理大型项目。

项目描述

什么是渐变?

https://github.com/PyAr/fades/actions/workflows/test.uaml/badge.svg Documentation Status https://badge.fury.io/py/fades.svg https://coveralls.io/repos/PyAr/fades/badge.svg?branch=master&service=github Snap Status Appveyor Status

fades 是一个系统,它自动处理在编写脚本和简单程序时通常遇到的情况下的虚拟环境,甚至帮助管理大型项目。

resources/logo256.png

fades 将自动创建一个新的虚拟环境(或重用之前创建的一个),安装必要的依赖项,并在该虚拟环境中执行您的脚本,唯一的要求是使用 fades 执行脚本,并标记所需的依赖项。

(如果您不知道为什么这是必要的或有用的,我建议您阅读有关 Python 和依赖项管理 的简短文本。)

第一个非选项参数(如果有)将是要执行的子程序,之后的任何其他参数都将原样传递给该子脚本。

fades 也可以在不传递要执行的子脚本的情况下执行:在这种模式下,它将在创建/重用的虚拟环境中打开一个 Python 交互式解释器(从 --dependency--requirement 选项中获取依赖项)。

如何使用它?

点击以下图片查看一个视频/屏幕录制,它展示了 fades 的主要功能只需 5 分钟...

resources/video/screenshot.png

...或者检查 这些几个小 GIF,每个 GIF 都展示了一个特定的 fades 功能,但请继续阅读以获取更多信息...

是的,请让我阅读

当您编写脚本时,您必须采取两项特殊措施

  • 需要使用 fades(而不是 python)执行它

  • 需要标记那些依赖项

在执行脚本的那一刻,fades 将搜索带有标记依赖项的虚拟环境,如果不存在,fades 将创建它,并在该环境中执行脚本。

如何使用 fades 执行脚本?

您始终可以直接使用 fades 调用您的脚本

fades myscript.py

然而,为了确保您不会忘记 fades 并直接使用 python 执行它,最好在脚本的开头放置操作系统的指示,表明它应该使用 fades 执行...

#!/usr/bin/env fades

...并且也要设置脚本的可执行位

chmod +x yourscript.py

您还可以直接从网络执行脚本,直接传递粘贴脚本的地方的 URL(支持大多数粘贴板,如 pastebin.com、gist、linkode.org,如果 URL 直接指向脚本,也支持)

fades http://myserver.com/myscript.py

如何标记要安装的依赖项?

标记脚本导入的模块为 由 fades 安装的依赖项 的方法是通过使用注释。

此注释通常与导入语句在同一行(推荐,未来更少混淆和错误),但也可以放在前一行。

最简单的注释如下

import somemodule   # fades
from somepackage import othermodule    # fades

fades 是强制性的,在此示例中,仓库是 PyPI,关于其他示例请参阅下方的 不同仓库的说明

有了这条注释,fades 将自动在虚拟环境中安装 PyPI 上的 somemodulesomepackage

此外,您还可以指定特定的版本条件,例如

import somemodule   # fades == 3
import somemodule   # fades >= 2.1
import somemodule   # fades >=2.1,<2.8,!=2.6.5

有时,项目本身与模块名称不匹配;在这些情况下,您可以指定项目名称(可选,在版本之前)

import bs4   # fades beautifulsoup4
import bs4   # fades beautifulsoup4 == 4.2

如果没有提供要执行的脚本怎么办?

如果没有传递脚本或程序执行,fades 将提供包含所有指定依赖关系的虚拟环境,然后在虚拟环境上下文中打开交互式解释器。

在这种情况下,-i/--ipython 选项非常有用,如果该 REPL 比标准 REPL 更受青睐。

在使用交互式解释器的情况下,自动导入所有指定依赖关系也非常有用,可以通过传递 --autoimport 参数来实现。

其他指定依赖项的方法

除了在源文件中标记导入之外,还有其他方法告诉 fades 在虚拟环境中安装哪些依赖关系。

一种方法是通过命令行,传递 --dependency 参数。此选项可以多次指定(每个依赖关系一次),每次的格式是 repository::dependency。依赖关系可以有版本说明,仓库是可选的(默认为‘pypi’)。

另一种方法是在文本文件中指定依赖关系,每行一个依赖关系,每行的格式与 --dependency 参数之前描述的格式相同。然后通过 --requirement 参数将该文件指示给 fades。此选项可以多次指定。

如果定义了相同的依赖关系的多个实例,则命令行将覆盖所有其他内容,而需求文件将覆盖源代码中指定的内容。

最后,您可以在脚本文档字符串中包含包名称,在写有“fades”的行之后,直到文档字符串的末尾;例如

"""Script to do stuff.

It's a very important script.

We need some dependencies to run ok, installed by fades:
    request
    otherpackage
"""

关于不同的仓库

fades 支持从多个仓库安装所需的依赖关系:除了 PyPI 之外,您还可以指定指向 GitHub、Launchpad 等项目的 URL(基本上,所有由 pip 本身支持的项目)。

当指定依赖关系时,fades 会推断正确的仓库。例如,在以下示例中,fades 将在第一个情况下从 PyPI 安装 requests 的最新修订版,在第二个情况下从 GitHub 的项目本身安装最新修订版。

-d requests
-d git+https://github.com/kennethreitz/requests.git#egg=requests

如果您愿意,可以明确指出 fades 应使用哪种类型的仓库,通过在依赖关系前加上特殊标记双冒号(::)来实现。

-d pypi::requests
-d vcs::git+https://github.com/kennethreitz/requests.git#egg=requests

有两个基本仓库:pypi,将使 fades 从 PyPI 安装所需的依赖关系,以及 vcs,将使 fades 将依赖关系视为版本控制系统网站的 URL。在前者的情况下,对于 PyPI,可以指定全范围的版本比较器,如通常一样。对于 vcs 仓库,尽管如此,比较始终是精确的:如果指定了相同的依赖关系,则重用 virtualenv,否则将创建一个新的并填充它。

在两种情况下(显式或隐式指定仓库)都没有区别,无论是通过命令行、requirements.txt 文件、脚本文档字符串等方式指定依赖项。在脚本中直接标记 import 的情况下略有不同。

在标记 import 时,通常情况是待安装的包的名称与导入的模块名称相同,因此只能在 PyPI 上找到。因此,在以下情况下,pypi 仓库不仅被推导出来,而且是不可避免的。

import requests  # fades
from foo import bar  # fades
import requests  # fades <= 3

但是,如果指定了包(通常需要因为它与模块名称不同),或者指定了版本控制系统 URL,那么上述提到的可能性都是可用的:让 fades 推导适当的仓库或显式标记它。

import bs4  # fades beautifulsoup
import bs4  # fades pypi::beautifulsoup
import requests  # fades git+https://github.com/kennethreitz/requests.git#egg=requests
import requests  # fades vcs::git+https://github.com/kennethreitz/requests.git#egg=requests

关于 vcs 仓库的最后一个细节:编写 URL 的格式与 pip 本身支持的格式相同(有关更多详细信息,请参阅 pip 文档)。

此外,您可以从本地项目安装。使用以 file: 开头的依赖项是没有问题的。例如(请注意三斜线,因为我们正在将协议指示与路径混合)

fades -d file:///home/crazyuser/myproject/allstars/

如何控制虚拟环境的创建和使用?

您可以影响与 virtualenv 相关的所有过程的多个细节。

最重要的细节是 virtualenv 将使用哪个版本的 Python。当然,您需要在系统中安装相应的 Python 版本,但您可以精确控制使用哪个版本。

无论您以何种方式执行脚本(见上文),您都可以传递一个 -p--python 参数,仅用数字(2.7)、完整名称(python2.7)或完整路径(/usr/bin/python2.7)来指定要使用的 Python 版本。

其他细节是 fades 在说明正在做什么时的详细程度。默认情况下,fades 只会使用 stderr 来告知正在创建虚拟环境,并让用户知道正在执行需要活跃网络连接的操作(例如,安装新的依赖项)。

如果您使用 -v--verbose 调用 fades,它将发送所有内部调试行到 stderr,这如果在出现任何问题时可能非常有用。另一方面,如果您传递 -q--quiet 参数,fades 将不会显示任何内容(除非它真的有问题),因此原始脚本的 stderr 完全不会被污染。

如果您想使用 IPython shell,您需要使用 -i--ipython 选项调用 fades。此选项将 IPython 添加为 fades 的依赖项,并将启动此 shell 而不是 Python shell。

您还可以使用 --system-site-packages 来创建一个可以访问系统库的 venv。

最后,无论虚拟环境是如何创建的,您都可以使用 --get-venv-dir 选项在您的系统中始终获取虚拟环境的基本目录。

在虚拟环境中运行程序

-x/--exec 参数允许您在 virtualenv 的上下文中执行任何程序(而不仅仅是 Python 程序)。

默认情况下,必须给出的参数被认为是可执行文件名称,相对于虚拟环境的 bin 目录,因此这对于通过声明的依赖项执行安装的脚本/程序特别有用。例如。

fades -d flake8 -x flake8 my_script_to_be_verified_by_flake8.py

请注意,您可以传递一个绝对路径,并且它将被尊重(但不能传递一个相对路径,因为它将取决于虚拟环境的位置)。

例如,如果你想运行一个shell脚本,该脚本又运行一个需要在virtualenv环境中执行的Python程序,你可以这样做

fades -r requirements.txt --exec /var/lib/foobar/special.sh

最后,如果你打算运行的是作为模块执行的代码(你通常会用python3 -m some_module运行),你可以在virtualenv中使用相同的参数来运行该模块

fades -r requirements.txt -m some_module

如何处理 PyPI 中升级的包?

当你告诉fades使用一个依赖项创建virtualenv并且没有指定版本时,它会从PyPI安装最新版本。

例如,你执行fades -d foobar,它会安装7.0版本的foobar。在某个时候,foobar在PyPI上发布了新版本8.0,但如果再次执行fades -d foobar,它将只是重用之前创建的版本为7.0的virtualenv,不会下载新版本并创建一个带有新版本的新的virtualenv!

你可以告诉fades这样做,只需这样做

fades -d foobar --check-updates

…然后fades将在PyPI上搜索该包的更新,并发现版本8.0后,将使用最新版本创建一个新的virtualenv。

从那时起,如果你请求fades -d foobar,它将带有一个新版本的virtualenv。如果你想为任何依赖项获取一个不是最新版本的virtualenv,只需指定正确的版本。

你甚至可以在指定包版本时使用--check-updates参数。假设你调用fades -d foobar==7fades将安装7.0版本,无论哪个版本是最新的。但如果你这样做

fades -d foobar==7 --check-updates

…它仍然会使用版本7.0,但会通知你有一个新版本可用!

关于依赖项固定怎么办?

fades的一个很好的好处是,每次你的项目中的依赖项发生变化时,你实际上都会自动使用一个新的virtualenv。

如果你没有在requirements文件中锁定依赖项,这将产生另一个很好的副作用:每次你在新的环境中使用它们(或者如果你设置了–check-updates)时,你将获得最新版本,有效地避免了永远停留在旧版本中的陷阱。

然而,这也有一个坏处。如果在你运行测试和你的项目部署到服务器之间,你的项目的某个依赖项发布了一个修订版,那么你实际上可能会在生产环境中使用一个未经测试的组合。此外,即使你确实锁定了依赖项,这些依赖项的依赖项可能没有被锁定,你可能会陷入相同的境地。

例如,你可能有一个requests == 2.19.1的依赖项,但requests声明了自己的依赖项,例如chardet >= 3.0.2,在本地运行测试时,你可能得到的是chardet的版本3.0.3,但没有任何保证当你将你的项目部署到服务器(实际上是从头开始构建一切)时,你不会得到chardet的新版本,这可能是完全正常的,但事实上它是你没有在本地测试的事情。

在这里,fades通过使用–freeze选项来挽救局面。如果给出了这个参数,fades将像通常一样运行,但还会将pip freeze的结果输出到指定的文件。

所以,继续上面的例子,你可以像这样运行你的测试

fades -d "requests == 2.19.1" --freeze=reqs-frozen.txt -x python3 -m unittest

…这将为你留下一个类似以下内容的reqs-frozen.txt文件

certifi==2018.4.16
chardet==3.0.4
pip==18.0
requests==2.19.1
...

然后您可以使用该文件进行部署,该文件已将所有软件包固定,因此您将得到您所期望的。

内部选项

对于特定的用例,您可以向 virtualenvpippython 发送特定的参数。分别使用 --virtuaenv-options--pip-options--python-options。您必须为每个参数使用该参数。

示例

fades -d requests --virtualenv-options="--always-copy" --virtualenv-options="--extra-search-dir=/tmp"

fades -d requests --pip-options="--index-url='http://example.com'"

fades --python-options=-B foo.py

使用配置文件设置选项

您还可以使用 .ini 配置文件来配置 fades。fades 将在 /etc/fades/fades.ini 中搜索配置文件,搜索系统路径指示的路径(例如 ~/config/fades/fades.ini)和 .fades.ini

因此,您可以在系统、用户和项目级别拥有不同的设置。

安装 fades 后,您可以让您的配置目录运行

python -c "from fades.helpers import get_confdir; print(get_confdir())"

配置文件是 .ini 格式。(configparser)并且 fades 将搜索 [fades] 部分。

您必须使用与 CLI 中相同的配置。唯一的区别是带有短划线的配置选项,必须将其替换为下划线。

[fades]
ipython=true
verbose=true
python=python3
check_updates=true
dependency=requests;django>=1.8  # separated by semicolon

在 fades 处理这些设置方面存在一些细微差别:“依赖”、“pip 选项”和“virtualenv 选项”。在这些情况下,您必须使用分号分隔的列表。

最重要的是,这些选项将合并。因此,如果您在 /etc/fades/fades.ini 中配置“依赖 = requests”,您将在 fades 创建的所有虚拟环境中都有 requests。

如何清理旧虚拟环境?

当使用 fades 虚拟环境时,您不需要考虑这些环境。 fades 将做正确的事情并创建一个符合所需依赖项的新虚拟环境。但是,在某些情况下,您可能希望清理磁盘上的不必要的虚拟环境。

通过以 --rm 参数运行 fades,如果存在匹配提供的 UUID 的虚拟环境,则 fades 将删除该虚拟环境(一个找到虚拟环境 UUID 的简单方法是使用 --get-venv-dir 选项调用 fades)。

另一种清理缓存的方法是删除长时间未使用的所有 venv。为此,您需要使用 --clean-unused-venvs 调用 fades。当 fades 使用此选项时,它将在维护模式下运行,这意味着 fades 将在完成此任务后退出。所有未使用超过指定参数值的天的虚拟环境都将被删除。

建议您以某种自动方式运行此选项;即,添加一个 cron 任务来执行此命令

fades --clean-unused-venvs=42

一些命令行示例

fades 下执行 foo.py,将 --bar 参数传递给子程序,在源代码中指示的依赖项的虚拟环境中

fades foo.py --bar

fades 下执行 foo.py,显示所有 fades 消息(详细模式)

fades -v foo.py

fades 下执行 foo.py(将其 --bar 参数传递给它),在源代码中指示的依赖项的虚拟环境中,以及 dependency1dependency2(任何版本 > 3.2)

fades -d dependency1 -d "dependency2>3.2" foo.py --bar

在安装了 dependency1 的虚拟环境中运行 Python 交互式解释器

fades -d dependency1

在虚拟环境中安装所有从 requirements.txt 文件中获取的依赖项后,执行 Python 交互式解释器

fades -r requirements.txt

在虚拟环境中安装所有从文件 requirements.txtrequirements_devel.txt 中获取的依赖项后,执行 Python 交互式解释器

fades -r requirements.txt -r requirements_devel.txt

使用 django-admin.py 脚本启动名为 foo 的新项目,无需事先安装 django

fades -d django -x django-admin.py startproject foo

从磁盘和缓存索引中删除与给定 uuid 匹配的虚拟环境

fades --rm 89a2bf83-c280-4918-a78d-c35506efd69d

从给定的 pastebin 下载脚本并执行它(当然,在执行之前先构建一个虚拟环境,其中包含该 pastebin 中指示的依赖项)

fades http://linkode.org/#4QI4TrPlGf1gK2V7jPBC47

在一个项目中运行所有测试(直接作为模块运行 pytest 以获得更好的行为),并同时冻结依赖项以供后续部署

fades -r requirements.txt --freeze -m pytest -v

一些在项目脚本中使用 fades 的示例

在项目辅助脚本中包含 渐变 可以使您在处理该项目时不必担心虚拟环境的激活/取消激活,同时还可以解决如果依赖项发生变化则需要更新/更改/修复已创建的虚拟环境的问题。

这是一个运行您项目的脚本可能看起来的样子示例

#!/bin/sh
if (command -v fades > /dev/null)
then
    # fades FTW!
    fades -r requirements.txt bin/start
else
    echo 2
    # hope you are in the correct virtualenv
    python3 bin/start
fi

要运行测试,有一个同时处理开发依赖项的脚本非常有用

#!/bin/sh
fades -r requirements.txt -r reqs-dev.txt -x python -m pytest -s "$@"

如果我的系统中的 Python 被更新了怎么办?

由 fades 创建的虚拟环境依赖于创建它们时使用的 Python 版本,考虑到其主要和次要版本。

这意味着如果在运行 fades 时使用了一个 Python 版本,然后再次使用不同的 Python 版本运行它,它可能需要创建一个新的虚拟环境。

让我们看看一些示例。假设您使用 python 运行 fades,这是指向 /usr/bin/python3.4 的符号链接(直接手动运行或因为 fades 安装为使用该 Python 版本)。

如果您在系统中安装了 Python 3.4.2,并且它已升级到 Python 3.4.3,fades 将继续重用已创建的虚拟环境,因为只有微版本发生了变化,没有次要或主要版本。

但是,如果系统中安装了 Python 3.5,并且默认的 python 指向这个新版本,fades 将开始使用这个新版本重新创建所有虚拟环境。

这是好事,因为您希望虚拟环境中使用一个特定 Python 版本安装的依赖项继续由相同的 Python 版本使用。

但是,如果您想避免这种行为,请确保始终使用特定的 Python 版本(例如 /usr/bin/python3.4python3.4),这样就不会介意系统中是否有新版本可用。

如何安装它

在不同平台上安装 fades 的几个说明。

最简单的方法

在某些系统中,您可以直接安装 fades,无需事先安装任何依赖项。

如果您在 debian 不稳定版或测试版中,只需这样做

sudo apt-get install fades

对于 Arch Linux,您可以使用任何 AUR 辅助工具AUR 安装它,例如使用 pikaur

pikaur -S fades

在具有 Snaps 的系统中

sudo snap install fades –classic

(为什么是 –classic?因为这是 fades 在 snap 内部访问系统其余部分的唯一方式,以防您想使用不同的 Python 版本,或需要编译的依赖项等)。

对于 Mac OS X(以及 Homebrew

brew install fades

否则,继续阅读以了解如何首先安装依赖项,并在您的系统中淡入

依赖项

除了需要Python 3.3或更高版本外,fades还依赖于pkg_resources包,该包随setuptools一起提供。它在几乎所有地方都安装了,但无论如何,您可以在Ubuntu/Debian中使用以下命令安装它:

apt-get install python3-setuptools

在Arch Linux上使用:

pacman -S python-setuptools

它还依赖于python-xdg包。这个包应该安装在任何带有freedesktop.org GUI的GNU/Linux操作系统上。然而,它是一个可选依赖项。

您可以在Ubuntu/Debian中使用以下命令安装它:

apt-get install python3-xdg

在Arch Linux上使用:

pacman -S python-xdg

Fades还需要virtualenv包来支持子执行时的不同Python版本。(请参阅--python选项。)

对于其他 Debian 和 Ubuntu

如果您不在debian不稳定或测试版(如果您是,请参阅上面的说明以获得更好的说明),则可以使用此.deb

下载并执行以下操作安装它:

sudo dpkg -i fades_*.deb

如果你想使用 pip

pip3 install fades

多平台存档

最后,您始终可以获取多平台tar包,并以传统方式安装它

wget http://ftp.debian.org/debian/pool/main/f/fades/fades_9.0.1.orig.tar.gz
tar -xf fades_*.tar.gz
cd fades-*
sudo ./setup.py install

我可以不安装它来试用吗?

是的!分支项目并使用可执行文件

git clone https://github.com/PyAr/fades.git
cd fades
bin/fades your_script.py

Windows 呢?

Windows是fades支持的平台。

然而,我们没有合适的Windows安装程序(.exe或.msi),但您可以使用pip安装它,或从tar包安装它,或直接从项目中尝试它。所有这些选项都已在上面正确描述。

我们确实想要一个Windows安装程序。如果您能在这方面帮助我们,请与我们联系。我们还希望有一个在Windows上运行的Travis,这样GitHub在合并任何代码之前也会在这个平台上运行所有测试。谢谢!

获取一些帮助,提供一些反馈

您可以在邮件列表中提出任何问题或发送任何建议或请求。

在IRC上与我们聊天。#fades频道位于Freenode网络。

此外,您还可以在此(如果您发现任何问题,请务必这样做!)打开一个问题。

提前感谢您的宝贵时间。

如何开发 fades 本身

快速指南,帮助您在fades开发中快速启动。

获取代码

克隆项目

git clone git@github.com:PyAr/fades.git

安装依赖项

fades管理自己的依赖项,因此不需要安装任何其他内容。

要尝试它,只需执行以下操作:

bin/fades -V

如何运行测试

在开始开发时,始终,尤其是在合并新分支之前,您需要确保所有测试都通过。

实际上,这非常简单,只需运行

./test

这将不仅检查测试用例,还会检查代码是否符合美学建议,以及README文档的格式是否正确。

如果您只想运行一个特定的测试,只需指定它。例如:

./test tests.test_main:DepsMergingTestCase.test_two_different

开发流程

只需从列表中选择一个问题。

开发,确保./test运行正常,提交,推送,创建拉取请求等。

请,如果您旨在创建带有新代码(功能或修复)的拉取请求,请包括您更改的测试。

谢谢!祝您玩得开心。

项目详情


下载文件

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

源代码分发

fades-9.0.2.tar.gz (70.9 kB 查看哈希值)

上传时间 源代码

支持者