在 python 脚本中使用 conda install
Using conda install within a python script
根据此 answer 您可以从 Python 脚本中导入 pip 并使用它来安装模块。 conda install
可以做到这一点吗?
conda 文档仅显示命令行中的示例,但我正在寻找可以从 Python 脚本中执行的代码。
是的,我可以从脚本中执行 shell 命令,但我试图避免这种情况,因为它基本上假设无法导入 conda 并调用其函数。
试试这个:
!conda install xyzpackage
请记住这必须在 Python 脚本而不是 OS 提示中完成。
否则您可以尝试以下操作:
import sys
from conda.cli import main
sys.exit(main())
try:
import conda
from conda.cli import main
sys.argv = ['conda'] + list(args)
main()
您可以使用 conda.cli.main
。例如,这会安装 numpy
:
import conda.cli
conda.cli.main('conda', 'install', '-y', 'numpy')
使用 -y
参数来避免交互问题:
-y, --yes Do not ask for confirmation.
我在查看最新的 Conda Python API 并注意到实际上只有 2 个 public 模块具有“非常 long-term 稳定性”:
conda.cli.python_api
conda.api
对于你的问题,我会使用第一个:
注意:下面的run_command()
将总是添加一个-y
/--yes
选项(即它不会要求确认)
import conda.cli.python_api as Conda
import sys
###################################################################################################
# The below is roughly equivalent to:
# conda install -y 'args-go-here' 'no-whitespace-splitting-occurs' 'square-brackets-optional'
(stdout_str, stderr_str, return_code_int) = Conda.run_command(
Conda.Commands.INSTALL, # alternatively, you can just say "install"
# ...it's probably safer long-term to use the Commands class though
# Commands include:
# CLEAN,CONFIG,CREATE,INFO,INSTALL,HELP,LIST,REMOVE,SEARCH,UPDATE,RUN
[ 'args-go-here', 'no-whitespace-splitting-occurs', 'square-brackets-optional' ],
use_exception_handler=True, # Defaults to False, use that if you want to handle your own exceptions
stdout=sys.stdout, # Defaults to being returned as a str (stdout_str)
stderr=sys.stderr, # Also defaults to being returned as str (stderr_str)
search_path=Conda.SEARCH_PATH # this is the default; adding only for illustrative purposes
)
###################################################################################################
使用上面的好处是它解决了使用 conda.cli.main()
: 时出现的问题(在上面的评论中提到)
...conda tried to interpret the comand line arguments instead of the arguments of conda.cli.main(), so using conda.cli.main() like this might not work for some things.
上面评论中的另一个问题是:
How [to install a package] when the channel is not the default?
import conda.cli.python_api as Conda
import sys
###################################################################################################
# Either:
# conda install -y -c <CHANNEL> <PACKAGE>
# Or (>= conda 4.6)
# conda install -y <CHANNEL>::<PACKAGE>
(stdout_str, stderr_str, return_code_int) = Conda.run_command(
Conda.Commands.INSTALL,
'-c', '<CHANNEL>',
'<PACKAGE>'
use_exception_handler=True, stdout=sys.stdout, stderr=sys.stderr
)
###################################################################################################
使用 Python 脚本中的 conda
一段时间后,我认为使用 subprocess
模块调用 conda
整体效果最好。在 Python 3.7+ 中,你可以这样做:
import json
from subprocess import run
def conda_list(environment):
proc = run(["conda", "list", "--json", "--name", environment],
text=True, capture_output=True)
return json.loads(proc.stdout)
def conda_install(environment, *package):
proc = run(["conda", "install", "--quiet", "--name", environment] + packages,
text=True, capture_output=True)
return json.loads(proc.stdout)
正如我在评论中指出的那样,conda.cli.main()
不适合外部使用。它直接解析 sys.argv
,因此如果您尝试在您自己的脚本中使用它和您自己的命令行参数,它们也会被提供给 conda.cli.main()
。
@YenForYang 的回答建议 conda.cli.python_api
更好,因为这是一个公开记录的 API 用于调用 conda
命令。但是,我发现它仍然有粗糙的边缘。 conda
在执行命令时建立内部状态(例如缓存)。通常使用和测试 conda 的方式是作为命令行程序。在那种情况下,这个内部状态在 conda
命令结束时被丢弃。使用 conda.cli.python_api
,您可以在单个进程中执行多个 conda
命令。在这种情况下,内部状态会继续存在,有时会导致意外结果(例如,缓存在执行命令时变得过时)。当然,conda
直接处理这个内部状态应该是可以的。我的观点只是,以这种方式使用 conda
并不是开发人员的主要关注点。如果您想要最可靠的方法,请使用 conda
开发人员打算使用它的方式——作为它自己的过程。
conda
是一个相当慢的命令,所以我不认为人们应该担心调用子进程的性能影响。正如我在另一条评论中指出的那样,pip
是与 conda
类似的工具,并在 its documentation that it should be called as a subprocess, not imported into Python.
中明确说明
我尝试并为我工作的更简单的事情是:
import os
try:
import graphviz
except:
print ("graphviz not found, Installing graphviz ")
os.system("conda install -c anaconda graphviz")
import graphviz
并确保您 运行 您的脚本是管理员。
我发现 conda.cli.python_api
和 conda.api
是有限的,从某种意义上说,它们都没有执行这样的命令的选项:
conda export env > requirements.txt
所以我使用带有标志 shell=True
的子进程来完成工作。
subprocess.run(f"conda env export --name {env} > {file_path_from_history}",shell=True)
其中 env
是要保存到 requirements.txt
的环境的名称。
根据此 answer 您可以从 Python 脚本中导入 pip 并使用它来安装模块。 conda install
可以做到这一点吗?
conda 文档仅显示命令行中的示例,但我正在寻找可以从 Python 脚本中执行的代码。
是的,我可以从脚本中执行 shell 命令,但我试图避免这种情况,因为它基本上假设无法导入 conda 并调用其函数。
试试这个:
!conda install xyzpackage
请记住这必须在 Python 脚本而不是 OS 提示中完成。
否则您可以尝试以下操作:
import sys
from conda.cli import main
sys.exit(main())
try:
import conda
from conda.cli import main
sys.argv = ['conda'] + list(args)
main()
您可以使用 conda.cli.main
。例如,这会安装 numpy
:
import conda.cli
conda.cli.main('conda', 'install', '-y', 'numpy')
使用 -y
参数来避免交互问题:
-y, --yes Do not ask for confirmation.
我在查看最新的 Conda Python API 并注意到实际上只有 2 个 public 模块具有“非常 long-term 稳定性”:
conda.cli.python_api
conda.api
对于你的问题,我会使用第一个:
注意:下面的run_command()
将总是添加一个-y
/--yes
选项(即它不会要求确认)
import conda.cli.python_api as Conda
import sys
###################################################################################################
# The below is roughly equivalent to:
# conda install -y 'args-go-here' 'no-whitespace-splitting-occurs' 'square-brackets-optional'
(stdout_str, stderr_str, return_code_int) = Conda.run_command(
Conda.Commands.INSTALL, # alternatively, you can just say "install"
# ...it's probably safer long-term to use the Commands class though
# Commands include:
# CLEAN,CONFIG,CREATE,INFO,INSTALL,HELP,LIST,REMOVE,SEARCH,UPDATE,RUN
[ 'args-go-here', 'no-whitespace-splitting-occurs', 'square-brackets-optional' ],
use_exception_handler=True, # Defaults to False, use that if you want to handle your own exceptions
stdout=sys.stdout, # Defaults to being returned as a str (stdout_str)
stderr=sys.stderr, # Also defaults to being returned as str (stderr_str)
search_path=Conda.SEARCH_PATH # this is the default; adding only for illustrative purposes
)
###################################################################################################
使用上面的好处是它解决了使用
conda.cli.main()
: 时出现的问题(在上面的评论中提到)
...conda tried to interpret the comand line arguments instead of the arguments of conda.cli.main(), so using conda.cli.main() like this might not work for some things.
上面评论中的另一个问题是:
How [to install a package] when the channel is not the default?
import conda.cli.python_api as Conda
import sys
###################################################################################################
# Either:
# conda install -y -c <CHANNEL> <PACKAGE>
# Or (>= conda 4.6)
# conda install -y <CHANNEL>::<PACKAGE>
(stdout_str, stderr_str, return_code_int) = Conda.run_command(
Conda.Commands.INSTALL,
'-c', '<CHANNEL>',
'<PACKAGE>'
use_exception_handler=True, stdout=sys.stdout, stderr=sys.stderr
)
###################################################################################################
使用 Python 脚本中的 conda
一段时间后,我认为使用 subprocess
模块调用 conda
整体效果最好。在 Python 3.7+ 中,你可以这样做:
import json
from subprocess import run
def conda_list(environment):
proc = run(["conda", "list", "--json", "--name", environment],
text=True, capture_output=True)
return json.loads(proc.stdout)
def conda_install(environment, *package):
proc = run(["conda", "install", "--quiet", "--name", environment] + packages,
text=True, capture_output=True)
return json.loads(proc.stdout)
正如我在评论中指出的那样,conda.cli.main()
不适合外部使用。它直接解析 sys.argv
,因此如果您尝试在您自己的脚本中使用它和您自己的命令行参数,它们也会被提供给 conda.cli.main()
。
@YenForYang 的回答建议 conda.cli.python_api
更好,因为这是一个公开记录的 API 用于调用 conda
命令。但是,我发现它仍然有粗糙的边缘。 conda
在执行命令时建立内部状态(例如缓存)。通常使用和测试 conda 的方式是作为命令行程序。在那种情况下,这个内部状态在 conda
命令结束时被丢弃。使用 conda.cli.python_api
,您可以在单个进程中执行多个 conda
命令。在这种情况下,内部状态会继续存在,有时会导致意外结果(例如,缓存在执行命令时变得过时)。当然,conda
直接处理这个内部状态应该是可以的。我的观点只是,以这种方式使用 conda
并不是开发人员的主要关注点。如果您想要最可靠的方法,请使用 conda
开发人员打算使用它的方式——作为它自己的过程。
conda
是一个相当慢的命令,所以我不认为人们应该担心调用子进程的性能影响。正如我在另一条评论中指出的那样,pip
是与 conda
类似的工具,并在 its documentation that it should be called as a subprocess, not imported into Python.
我尝试并为我工作的更简单的事情是:
import os
try:
import graphviz
except:
print ("graphviz not found, Installing graphviz ")
os.system("conda install -c anaconda graphviz")
import graphviz
并确保您 运行 您的脚本是管理员。
我发现 conda.cli.python_api
和 conda.api
是有限的,从某种意义上说,它们都没有执行这样的命令的选项:
conda export env > requirements.txt
所以我使用带有标志 shell=True
的子进程来完成工作。
subprocess.run(f"conda env export --name {env} > {file_path_from_history}",shell=True)
其中 env
是要保存到 requirements.txt
的环境的名称。