简体   繁体   English

在 python 脚本中使用 conda install

[英]Using conda install within a python script

According to this answer you can import pip from within a Python script and use it to install a module.根据此答案,您可以从 Python 脚本中导入 pip 并使用它来安装模块。 Is it possible to do this with conda install ?是否可以使用conda install来做到这一点?

The conda documentation only shows examples from the command line but I'm looking for code that can be executed from within a Python script. conda 文档仅显示命令行中的示例,但我正在寻找可以从 Python 脚本中执行的代码。

Yes, I could execute shell commands from within the script but I am trying to avoid this as it is basically assuming that conda cannot be imported and its functions called.是的,我可以从脚本中执行 shell 命令,但我试图避免这种情况,因为它基本上假设无法导入 conda 并调用其函数。

You can use conda.cli.main .您可以使用conda.cli.main For example, this installs numpy :例如,这将安装numpy

import conda.cli

conda.cli.main('conda', 'install',  '-y', 'numpy')

Use the -y argument to avoid interactive questions:使用-y参数来避免交互式问题:

-y, --yes Do not ask for confirmation. -y, --yes 不要求确认。

I was looking at the latest Conda Python API and noticed that there are actually only 2 public modules with “very long-term stability”:我正在查看最新的Conda Python API,并注意到实际上只有 2 个公共模块具有“非常长期的稳定性”:

  1. conda.cli.python_api
  2. conda.api

For your question, I would work with the first:对于您的问题,我将使用第一个:

NOTE : run_command() below will always add a -y / --yes option (ie it will not ask for confirmation )注意:下面的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
)
###################################################################################################


The nice thing about using the above is that it solves a problem that occurs (mentioned in the comments above) when using conda.cli.main() : 使用上面的conda.cli.main()是它解决了使用conda.cli.main()时出现的问题(在上面的评论中提到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. ...conda 试图解释命令行参数而不是 conda.cli.main() 的参数,因此像这样使用 conda.cli.main() 可能不适用于某些事情。


The other question in the comments above was:上面评论中的另一个问题是:

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 ) ###################################################################################################

Having worked with conda from Python scripts for a while now, I think calling conda with the subprocess module works the best overall.与工作过conda现在从Python脚本了一段时间,我想打电话condasubprocess模块的工作原理最佳的整体。 In Python 3.7+, you could do something like this:在 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)

As I pointed out in a comment, conda.cli.main() was not intended for external use.正如我在评论中指出的那样, conda.cli.main()不适合外部使用。 It parses sys.argv directly, so if you try to use it in your own script with your own command line arguments, they will get fed to conda.cli.main() as well.它直接解析sys.argv ,所以如果你尝试在你自己的脚本中使用你自己的命令行参数,它们也会被提供给conda.cli.main()

@YenForYang's answer suggesting conda.cli.python_api is better because this is a publicly documented API for calling conda commands. @YenForYang 的回答表明conda.cli.python_api更好,因为这是一个公开记录的用于调用conda命令的 API。 However, I have found that it still has rough edges.但是,我发现它仍然有粗糙的边缘。 conda builds up internal state as it executes a command (eg caches). conda在执行命令(例如缓存)时建立内部状态。 The way conda is usually used and usually tested is as a command line program. conda 通常使用和测试的方式是作为命令行程序。 In that case, this internal state is discarded at the end of the conda command.在这种情况下,这个内部状态在conda命令结束时被丢弃。 With conda.cli.python_api , you can execute several conda commands within a single process.使用conda.cli.python_api ,您可以在单个进程中执行多个conda命令。 In this case, the internal state carries over and can sometimes lead to unexpected results (eg the cache becomes outdated as commands are performed).在这种情况下,内部状态会继续存在,有时会导致意外结果(例如,执行命令时缓存变得过时)。 Of course, it should be possible for conda to handle this internal state directly.当然, conda应该可以直接处理这个内部状态。 My point is just that using conda this way is not the main focus of the developers.我的观点只是,以这种方式使用conda并不是开发人员的主要关注点。 If you want the most reliable method, use conda the way the developers intend it to be used -- as its own process.如果您想要最可靠的方法,请按照开发人员希望使用的方式使用conda —— 作为它自己的过程。

conda is a fairly slow command, so I don't think one should worry about the performance impact of calling a subprocess. conda是一个相当慢的命令,所以我认为人们不必担心调用子进程对性能的影响。 As I noted in another comment, pip is a similar tool to conda and explicitly states in its documentation that it should be called as a subprocess, not imported into Python .正如我在另一条评论中所指出的, pip是一个类似于conda工具,并在其文档中明确指出它应该被称为子进程,而不是导入到 Python 中

I found that conda.cli.python_api and conda.api are limited, in the sense that, they both don't have the option to execute commands like this:我发现conda.cli.python_apiconda.api是有限的,从某种意义上说,它们都没有执行这样的命令的选项:

conda export env > requirements.txt

So instead I used subprocess with the flag shell=True to get the job done.因此,我使用带有标志shell=True来完成工作。

subprocess.run(f"conda env export --name {env} > {file_path_from_history}",shell=True)

where env is the name of the env to be saved to requirements.txt .其中env是要保存到requirements.txt的 env 的名称。

Try this:尝试这个:

!conda install xyzpackage

Please remember this has to be done within the Python script not the OS prompt.请记住,这必须在 Python 脚本中完成,而不是在操作系统提示中完成。

Or else you could try the following:或者你可以尝试以下方法:

import sys
from conda.cli import main

    sys.exit(main())

    try:
        import conda
        from conda.cli import main
        sys.argv = ['conda'] + list(args)
        main()

The simpler thing that i tried and worked for me was :我尝试并为我工作的更简单的事情是:

import os

try:
    import graphviz
except:
    print ("graphviz not found, Installing graphviz ")
    os.system("conda install -c anaconda graphviz")
    import graphviz

And make sure you run your script as admin.并确保您以管理员身份运行脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM