有时我从github下载python源代码,不知道如何安装所有的依赖项。如果没有requirements.txt文件,我必须手工创建它。 问题是: 给定python源代码目录,是否有可能从导入部分自动创建requirements.txt ?


当前回答

如果遇到和我一样的问题,即不在虚拟环境中,并且想要特定项目的requirements.txt或从选定的文件夹(包括子)和pipreqs是不支持的。

你可以使用:

import os
import sys
from fuzzywuzzy import fuzz
import subprocess

path = "C:/Users/Username/Desktop/DjangoProjects/restAPItest"


files = os.listdir(path)
pyfiles = []
for root, dirs, files in os.walk(path):
      for file in files:
        if file.endswith('.py'):
              pyfiles.append(os.path.join(root, file))

stopWords = ['from', 'import',',','.']

importables = []

for file in pyfiles:
    with open(file) as f:
        content = f.readlines()

        for line in content:
            if "import" in line:
                for sw in stopWords:
                    line = ' '.join(line.split(sw))

                importables.append(line.strip().split(' ')[0])

importables = set(importables)

subprocess.call(f"pip freeze > {path}/requirements.txt", shell=True)

with open(path+'/requirements.txt') as req:
    modules = req.readlines()
    modules = {m.split('=')[0].lower() : m for m in modules}


notList = [''.join(i.split('_')) for i in sys.builtin_module_names]+['os']

new_requirements = []
for req_module in importables:
    try :
        new_requirements.append(modules[req_module])

    except KeyError:
        for k,v in modules.items():
            if len(req_module)>1 and req_module not in notList:
                if fuzz.partial_ratio(req_module,k) > 90:
                    new_requirements.append(modules[k])

new_requirements = [i for i in set(new_requirements)]

new_requirements

with open(path+'/requirements.txt','w') as req:
    req.write(''.join(new_requirements))

附注:它可能有一些额外的库,因为它检查模糊逻辑。

其他回答

自动更新requirements.txt的方法

在使用requirements.txt开发python应用程序时,我们有几个选择:

在开发完成后,当我们想要部署它时,生成requirements.txt。它由pip freeze > requirements.txt或pipreqs执行,以减少混乱的结果。 在每次安装后手动将每个模块添加到requirements.txt中。 安装管理器,它将为我们处理requirements.txt更新。

1-st选项有很多答案,2-d选项不言自明,所以我想描述3-d方法。有一个叫做to-requirements.txt的库。要安装它,输入以下命令:

pip install to-requirements.txt  # Pip install to requirements.txt

如果你一次阅读整个命令,你就会明白它是做什么的。安装后,您应该安装它。运行:

requirements-txt setup

它覆盖pip脚本,以便每个pip安装或pip卸载都自动使用所需版本的包更新项目的requirements.txt文件。重写是安全的,因此卸载此包后pip将正常运行。

你可以自定义它的工作方式。例如,全局禁用它,只在需要的目录中激活它,只在git存储库中激活它,或者允许/不允许创建requirements.txt文件(如果它不存在)。

链接:

文档- https://requirements-txt.readthedocs.io/en/latest/ GitHub - https://github.com/VoIlAlex/requirements-txt PyPI - https://pypi.org/project/to-requirements.txt/

如果你在你的系统中安装了很多依赖项,并且你需要一个特定项目的requirements.txt,你可以安装第一个pipreqs:

$ pip install pipreqs

并在项目文件夹下执行以下命令。

$ pipreqs

该命令将为特定项目生成requirements.txt文件。

在我的例子中,我使用Anaconda,所以在我的环境中从conda终端运行以下命令解决了这个问题,并自动为我创建了这个requirements.txt文件:

conda list -e > requirements.txt

这是从这个Github链接pratos/condaenv.txt

如果看到错误,并且您正在使用anaconda,请尝试使用.yml选项:

conda env export > <environment-name>.yml

供其他人使用该环境,或者如果您正在另一台机器上创建新环境:

conda env create -f <environment-name>.yml

.yml选项在这里找到

我创建了这个bash命令。

for l in $(pip freeze); do p=$(echo "$l" | cut -d'=' -f1); f=$(find . -type f -exec grep "$p" {} \; | grep 'import'); [[ ! -z "$f" ]] && echo "$l" ; done;

这个简单的任务在Python中如此复杂,真是令人惊叹。下面是我认为最好的自动完成的方法。

你需要两个工具:

1. pipreqs

Pip3安装pipreqs

Pipreqs会检查你的项目,只安装项目使用的包。而不是像pip freeze那样在python环境中执行所有包。

但这种方法有一个问题。它不安装子包。

例如,您的项目使用pandas==1.3.2。Pandas本身在其他包中使用numpy==1.21.2。但是pipreqs本身并不在requirements .txt中编写子包(即numpy)

这就是您需要将pipreqs与第二个工具结合使用的地方。

pip-tools

Pip3安装pip-tools

Pip-tools将接受需求中的包。并生成带有所有子包的requirements.txt。例如,如果你有 Pandas ==1.3.2的需求。在,pip-tools将生成

Numpy ==1.21.2 # via pandas in requirements.txt。

但是您需要手动在requirements.in中添加包。这很容易出错,你可能会偶尔忘记这样做。

在这里可以使用第一个工具。

但是这两个工具都是根据requirements.txt编写的。那么如何解决这个问题呢?

使用pipreqs的——savepath来写入需求。,而不是默认的requirements.txt。

一次命令就完成;只做

pipreqs——savepath =需求。在&& pip-compile

好了。现在您不需要担心手动维护包,并且您的requirements.txt将包含所有子包,因此您的构建是确定的。

博士TL;

Pip3安装pipreqs Pip3安装pip-tools

使用下面的代码构建确定性的requirements.txt

pipreqs——savepath =需求。在&& pip-compile