简体   繁体   English

在 Docker 容器中将参数传递给 Python argparse

[英]Pass arguments to Python argparse within Docker container

I am embarking on my first attempt at utilizing a docker container.我第一次尝试使用 docker 容器。 I have a python script that calls a couple API's and parses a file.我有一个 python 脚本,它调用几个 API 并解析一个文件。 The script took parameters for the URL of the server for the API, the API key, and the file path for the file to parse.该脚本采用 API 的服务器 URL、API 密钥和要解析的文件的文件路径等参数。 I used argparse to handle these in the script.我使用 argparse 在脚本中处理这些。

How do I get get these passed into Docker?我如何将这些传递到 Docker 中? I do not want to hard code anything as I am looking to hand this script off to an engineer who needs to run this periodically and take action based on the results.我不想硬编码任何东西,因为我希望将此脚本交给需要定期运行并根据结果采取行动的工程师。

Thanks for your help.感谢您的帮助。 I have been searching but it seems like hard coding things into the dockerfile is the suggestion - I want the user to be able to put these in at run time.我一直在搜索,但似乎建议将内容硬编码到 dockerfile 中 - 我希望用户能够在运行时将它们放入。 Or perhaps I have found the answer and am just not understanding it....或者也许我已经找到了答案,只是我不理解它......

I apologize if my lingo is not right - this is my first attempt at utilizing Docker.如果我的术语不正确,我深表歉意——这是我第一次尝试使用 Docker。

The way you do it depends on how your using docker.您这样做的方式取决于您使用 docker 的方式。 If you want to run your script in an already running container, you can use exec:如果要在已经运行的容器中运行脚本,可以使用 exec:

docker exec <yourContainerName> python <yourScript> <args>

Alternatively, if you have a docker image where your script is the ENTRYPOINT, any arguments you pass to the docker run command will be added to the entrypoint.或者,如果您有一个 docker 映像,其中您的脚本是入口点,则您传递给 docker run 命令的任何参数都将添加到入口点。

So, if your docker file looks like this:因此,如果您的 docker 文件如下所示:

FROM yourbase
....
ENTRYPOINT <yourScript>

Then you can just run the script by running the container itself:然后你可以通过运行容器本身来运行脚本:

docker run --rm <yourImageName> <args>

Based on your comment below, it looks like you want this option.根据您在下面的评论,您似乎想要此选项。 You should change your dockerfile to specify您应该更改 dockerfile 以指定

ENTRYPOINT ["python","./script.py"]

(instead of using CMD) and then you can run via: (而不是使用 CMD),然后您可以通过以下方式运行:

docker run --rm <yourImageName>  -a API_KEY - f FILENAME -o ORG_ID

So let's assume your command is below所以让我们假设你的命令在下面

python app.py "URL" "APIKEY" "filepath"

So you will put your Dockerfile in below fashion因此,您将以以下方式放置 Dockerfile

FROM python:3.6
WORKDIR /app
COPY app.py .
ENTRYPOINT ["python", "app.py"]

Then the person running the docker container would do it like below然后运行 ​​docker 容器的人会像下面那样做

docker run -v /home/tarun/project/filetoparse.yaml:/config.yaml <yourimagename> "URL" "APIKEY" /config.yaml

If you want to give more flexibility you an can even use environment variables如果您想提供更大的灵活性,您甚至可以使用环境变量

docker run -v /home/tarun/project/filetoparse.yaml:/config.yaml -e APIKEY="XYZ" <dockerimage> "URL" /config.yaml

And then in your script you can read it using os.environ['APIKEY']然后在您的脚本中,您可以使用os.environ['APIKEY']读取它

Inside Dockerfile , i use the CMD command like this:Dockerfile ,我使用这样的CMD命令:

FROM python:3
COPY ./app /app
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r req.pip
CMD ["python","start.py","(api-url) ","(api-key)","(file-path)"]

Note Per each args/params, separate with coma注意每个参数/参数,用昏迷分开

If you are using flags, you will need to split如果您使用标志,则需要拆分

CMD ["python","start.py","-u","(api-url) ","-k","(api-key)","-f","(file-path)"]

This answer is kind of late but for any future readers, i would like to make it more towards the question asked ie with respect to argparse.这个答案有点晚了,但对于任何未来的读者,我想更倾向于提出的问题,即关于 argparse。

The basic idea like @Chris pointed out is it.像@Chris 指出的基本思想就是它。 One way to achieve the solution is to pass arguments to the image in docker run command itself.实现解决方案的一种方法是在 docker run 命令本身中将参数传递给image These arguments would then be passed to your ENTRYPOINT , therefore passing to the python script.然后将这些参数传递给您的ENTRYPOINT ,从而传递给 python 脚本。

The files would look something like this typically..这些文件通常看起来像这样..

file.py文件.py

import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('pos', type=str, help='Example Positional Argument') # will be accesible under args.POS
parser.add_argument('--opt', type=str , help='Example Optional Argument') # will be accesible with args.OPT

args = parser.parse_args()

# do something with pos and OPT

Without docker, You would run this file (assuming it is in the pwd) as python file.py --opt opt_val pos_val如果没有 docker,你会运行这个文件(假设它在密码中)作为python file.py --opt opt_val pos_val

Dockerfile文件

FROM python:<your_tag>
COPY ./file.py ./ # Assuming your Dockerfile and file.py are in the same directory

# some custom build steps

ENTRYPOINT ["python","./file.py"]

Docker build and run commands Docker 构建和运行命令

You build with this : docker build --tag example:0.0.1 <dir>你用这个docker build --tag example:0.0.1 <dir>

The below shows multiline(for better readability) run commands,下面显示了多行(为了更好的可读性)运行命令,

Docker run运行 Docker

docker run --rm \
   --name example.container \
   example:0.0.1 \
   --opt=opt_val \
   POS=pos_value

Docker run (powershell) Docker 运行(powershell)

docker run --rm `
   --name example.container `
   example:0.0.1 `
   --opt=opt_val `
   POS=pos_value

So here are some points to remember:所以这里有一些要点要记住:

  • Argparse has support for adding positional and optional arguments and should be passed accordingly to the image in the docker run command. Argparse 支持添加位置和可选参数,并且应该相应地传递给 docker docker run命令中的image
  • The solution pointed out above works but is not as flexible as id generally like it to be.上面指出的解决方案有效,但不像 id 通常喜欢的那样灵活。 Better to use Environment variables and access inside the script with os.environ() .最好使用环境变量并通过os.environ()访问脚本os.environ()
  • With this solution you dont "hard-code" anything to the Dockerfile使用此解决方案,您无需对 Dockerfile 进行任何“硬编码”

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

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