gpt4 book ai didi

python - 从Docker容器使用Flask send_from_directory返回空的tar.gz文件

转载 作者:行者123 更新时间:2023-12-02 19:20:07 31 4
gpt4 key购买 nike

在Docker上进行Flask实验时,我成功地通过HTML表单使用了用户输入,运行了一个流程,然后创建了一个包含流程输出的tarball。我正在尝试在一堆临时目录中进行文件处理。

我已经通过终端查询了容器文件系统:我的进程正在按预期运行,并且tar.gz文件已成功创建。 tar -xzf myfile.tar.gz确实为我提供了所需的信息。

但是,当我通过网络服务器下载tar.gz文件时,它是空的。

我正在创建文件,如下所示:

def create_tarball(client_directory, output_directory):
'''Creates a tarball from generated client files

Args:
client_directory: location of files to add to the tarball
target_directory: location to save the created tarball
'''
os.chdir(output_directory)
t = tarfile.open('client.tar.gz', mode='w:gz')
t.add(client_directory, arcname='cloud-run-client')
t.close()

这是 /download路线:
@app.route('/download', methods=["GET"])
def download():
return send_from_directory(
directory=app.config["DOWNLOAD_DIR"],
filename='client.tar.gz',
as_attachment=True
)

我的flask应用程序的Config类如下所示:
import tempfile

class Config(object):
# ...
UPLOAD_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')
DOWNLOAD_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')
CLIENT_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')
#...

我也尝试过创建标准目录(而不是Python临时文件),但无济于事-空压缩包的结果相同。

最佳答案

仅给出了代码,我无法重现该问题。

Dockerfile:

FROM ubuntu:18.04

# python3-pip will make pip available for python3.7
RUN apt-get update && \
apt-get install --yes python3.7 python3-pip

RUN python3.7 -m pip install -q flask

WORKDIR /app

COPY example.py /app

ENTRYPOINT [ "python3.7" ]

CMD [ "example.py" ]

构建docker镜像(为简洁起见,缓存输出):
$ docker build -t flask-example:latest .
Sending build context to Docker daemon 9.624MB
Step 1/7 : FROM ubuntu:18.04
---> 72300a873c2c
Step 2/7 : RUN apt-get update --quiet --yes && apt-get install --quiet --yes python3.7 python3-pip
---> Using cache
---> defecdbab68a
Step 3/7 : RUN python3.7 -m pip install -q flask
---> Using cache
---> ac5d72995a2d
Step 4/7 : WORKDIR /app
---> Using cache
---> ad1c0e2d4290
Step 5/7 : COPY example.py /app
---> 8422399a2979
Step 6/7 : ENTRYPOINT [ "python3.7" ]
---> Running in 10a0f0f161a5
Removing intermediate container 10a0f0f161a5
---> ede44f15a658
Step 7/7 : CMD [ "example.py" ]
---> Running in 385c2fab77ff
Removing intermediate container 385c2fab77ff
---> c3a4febfeee6
Successfully built c3a4febfeee6
Successfully tagged flask-example:latest

该代码以及您的示例,并为tarball编写了一个伪文件:

#!/usr/bin/python3.7

from flask import Flask, escape, request, send_from_directory
import os
import tempfile
import tarfile
import datetime
from pathlib import Path

class Config(object):
UPLOAD_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')
DOWNLOAD_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')
CLIENT_DIR = tempfile.mkdtemp(prefix='/tmp/', dir='/')

app = Flask(__name__)
app.config.from_object('example.Config')

@app.route('/')
def hello():
name = request.args.get("name", "World")
return f'Hello, {escape(name)}!'

def create_tarball(client_directory, output_directory):
'''Creates a tarball from generated client files

Args:
client_directory: location of files to add to the tarball
target_directory: location to save the created tarball
'''
os.chdir(output_directory)
app.logger.debug("Contents: %s", os.listdir(client_directory))
t = tarfile.open('client.tar.gz', mode='w:gz')
t.add(client_directory, arcname='cloud-run-client')
t.close()
app.logger.debug("Results: %s", os.listdir(output_directory))

@app.route('/populate', methods=["GET"])
def populate_files():
out = Path(app.config["CLIENT_DIR"]) / 'output.txt'
with open(out, 'w') as fhandle:
fhandle.write(f"{datetime.datetime.now()} Example output\n")
app.logger.debug("Contents: %s", os.listdir(app.config["CLIENT_DIR"]))
create_tarball(app.config["CLIENT_DIR"], app.config["DOWNLOAD_DIR"])
return '200'

@app.route('/download', methods=["GET"])
def download():
return send_from_directory(
directory=app.config["DOWNLOAD_DIR"],
filename='client.tar.gz',
as_attachment=True
)

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

运行容器:
$ docker run --rm -p 5000:5000 flask-example:latest
* Serving Flask app "example" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 205-573-930
172.17.0.1 - - [10/Mar/2020 03:55:58] "GET /?name=me HTTP/1.1" 200 -
[2020-03-10 03:56:01,271] DEBUG in example: Contents: ['output.txt']
[2020-03-10 03:56:01,272] DEBUG in example: Contents: ['output.txt']
[2020-03-10 03:56:01,276] DEBUG in example: Results: ['client.tar.gz']
172.17.0.1 - - [10/Mar/2020 03:56:01] "GET /populate HTTP/1.1" 200 -
172.17.0.1 - - [10/Mar/2020 03:56:03] "GET /download HTTP/1.1" 200 -

客户输出:
$ curl http://localhost:5000/?name='me'
Hello, me!

$ curl http://localhost:5000/populate
Tarball created

$ curl --output - http://localhost:5000/download | tar tzv
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 197 100 197 0 0 65666 0 --:--:-- --:--:-- --:--:-- 65666
drwx------ root/root 0 2020-03-09 20:56 cloud-run-client/
-rw-r--r-- root/root 42 2020-03-09 20:56 cloud-run-client/output.txt

关于python - 从Docker容器使用Flask send_from_directory返回空的tar.gz文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60595037/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com