如何使用argparse将二进制文件作为stdin传递到Docker容器化的Python脚本?-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

如何使用argparse将二进制文件作为stdin传递到Docker容器化的Python脚本?

几许相思几点泪 2019-12-24 21:25:41 213

以在主机系统上有一个文件/tmp/test.txt且要head在其上使用但在Docker容器中的情况下(echo 'Hello World!' > /tmp/test.txt重现我的示例数据)为例:

您可以运行:

docker run -i busybox head -1 - < /tmp/test.txt

将第一行打印到屏幕上:

要么

cat /tmp/test.txt | docker run -i busybox head -1 -

输出为:

Hello World!

即使使用.xlsx这样的二进制格式而不是纯文本格式,也可以完成上述操作,并且您会得到一些奇怪的输出,类似于:

�Oxl/_rels/workbook.xml.rels���j�0

                              ��}

上面的要点是,即使通过Docker的抽象,head也可以使用二进制和文本格式。

但是在我自己的基于argparse的CLI(实际上是自定义Django管理命令,我相信它使用了argparse)中,尝试read_excel在Docker上下文中使用熊猫时出现以下错误。

打印的错误如下:

Traceback (most recent call last):
  File "./manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/opt/conda/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/opt/conda/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/opt/conda/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/opt/conda/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/home/jovyan/sequence_databaseApp/management/commands/seq_db.py", line 54, in handle
    df_snapshot = pd.read_excel(options['FILE'].buffer, sheet_name='Snapshot', header=0, dtype=dtype)
  File "/opt/conda/lib/python3.7/site-packages/pandas/util/_decorators.py", line 208, in wrapper
    return func(*args, **kwargs)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/excel/_base.py", line 310, in read_excel
    io = ExcelFile(io, engine=engine)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/excel/_base.py", line 819, in __init__
    self._reader = self._engines[engine](self._io)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/excel/_xlrd.py", line 21, in __init__
    super().__init__(filepath_or_buffer)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/excel/_base.py", line 356, in __init__
    filepath_or_buffer.seek(0)
io.UnsupportedOperation: File or stream is not seekable.

具体来说,

docker run -i <IMAGE> ./manage.py my_cli import - < /path/to/file.xlsx
不```  
起作用,

但是./manage.py my_cli import - < /path/to/file.xlsx 有效!

Docker上下文内有某种差异。

但是我也注意到,即使不考虑Docker:

```js
cat /path/to/file.xlsx | ./manage.py my_cli import -
不```  
起作用

虽然:

./manage.py my_cli import - < /path/to/file.xlsx 确实有效(如前所述)

最后,我正在使用的代码(您应该能够在管理/命令下将其另存为my_cli.py,以使其在Django项目中正常工作):

```js
import argparse


import sys


from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = 'my_cli help'

    def add_arguments(self, parser):
        subparsers = parser.add_subparsers(
            title='commands', dest='command', help='command help')
        subparsers.required = True
        parser_import = subparsers.add_parser('import', help='import help')
        parser_import.add_argument('FILE', type=argparse.FileType('r'), default=sys.stdin)

    def handle(self, *args, **options):
        import pandas as pd
        df = pd.read_excel(options['FILE'].buffer, header=0)
        print(df)
云服务器登录 云服务器设置
分享到
取消 提交回答
全部回答(0)
云原生
使用钉钉扫一扫加入圈子
+ 订阅

云原生时代,是开发者最好的时代

相似问题
最新问题