如何使用 Flask test_client 上传多个文件?
How do I upload multiple files using the Flask test_client?
如何使用 Flask test_client 将多个文件上传到一个 API 端点?
我正在尝试使用 Flask test_client 将多个文件上传到 Web 服务,该服务接受多个文件以将它们组合成一个大文件。
我的控制器是这样的:
@app.route("/combine/file", methods=["POST"])
@flask_login.login_required
def combine_files():
user = flask_login.current_user
combined_file_name = request.form.get("file_name")
# Store file locally
file_infos = []
for file_data in request.files.getlist('file[]'):
# Get the content of the file
file_temp_path="/tmp/{}-request.csv".format(file_id)
file_data.save(file_temp_path)
# Create a namedtuple with information about the file
FileInfo = namedtuple("FileInfo", ["id", "name", "path"])
file_infos.append(
FileInfo(
id=file_id,
name=file_data.filename,
path=file_temp_path
)
)
...
我的测试代码如下所示:
def test_combine_file(get_project_files):
project = get_project_files["project"]
r = web_client.post(
"/combine/file",
content_type='multipart/form-data',
buffered=True,
follow_redirects=True,
data={
"project_id": project.project_id,
"file_name": "API Test Combined File",
"file": [
(open("data/CC-Th0-MolsPerCell.csv", "rb"), "CC-Th0-MolsPerCell.csv"),
(open("data/CC-Th1-MolsPerCell.csv", "rb"), "CC-Th1-MolsPerCell.csv")
]})
response_data = json.loads(r.data)
assert "status" in response_data
assert response_data["status"] == "OK"
但是,我无法让 test_client 实际上传这两个文件。如果指定了多个文件,API 代码循环时 file_data 为空。我已经尝试了我自己的 ImmutableDict,其中包含两个 "file" 条目、一个文件元组列表、一个文件元组元组,以及我能想到的任何东西。
什么是API在Flasktest_client中指定多个文件上传?我在网上找不到这个! :(
测试客户端获取文件对象列表(由 open()
返回),所以这是我使用的测试实用程序:
def multi_file_upload(test_client, src_file_paths, dest_folder):
files = []
try:
files = [open(fpath, 'rb') for fpath in src_file_paths]
return test_client.post('/api/upload/', data={
'files': files,
'dest': dest_folder
})
finally:
for fp in files:
fp.close()
我认为如果您丢失元组(但保留 open()
s),那么您的代码可能会起作用。
另一种方法 - 如果你想在这里明确命名你的文件上传(我的用例是两个 CSV,但可以是任何东西)test_client 是这样的:
resp = test_client.post(
'/data_upload_api', # flask route
file_upload_one=[open(FILE_PATH, 'rb')],
file_upload_two=[open(FILE_PATH_2, 'rb')]
)
使用此语法,这些文件将可以访问为:
request.files['file_upload_one'] # etc.
您应该只发送数据对象和您想要命名的文件:
test_client.post('/api/upload',
data={'title': 'upload sample',
'file1': (io.BytesIO(b'get something'), 'file1'),
'file2': (io.BytesIO(b'forthright'), 'file2')},
content_type='multipart/form-data')
如何使用 Flask test_client 将多个文件上传到一个 API 端点?
我正在尝试使用 Flask test_client 将多个文件上传到 Web 服务,该服务接受多个文件以将它们组合成一个大文件。
我的控制器是这样的:
@app.route("/combine/file", methods=["POST"])
@flask_login.login_required
def combine_files():
user = flask_login.current_user
combined_file_name = request.form.get("file_name")
# Store file locally
file_infos = []
for file_data in request.files.getlist('file[]'):
# Get the content of the file
file_temp_path="/tmp/{}-request.csv".format(file_id)
file_data.save(file_temp_path)
# Create a namedtuple with information about the file
FileInfo = namedtuple("FileInfo", ["id", "name", "path"])
file_infos.append(
FileInfo(
id=file_id,
name=file_data.filename,
path=file_temp_path
)
)
...
我的测试代码如下所示:
def test_combine_file(get_project_files):
project = get_project_files["project"]
r = web_client.post(
"/combine/file",
content_type='multipart/form-data',
buffered=True,
follow_redirects=True,
data={
"project_id": project.project_id,
"file_name": "API Test Combined File",
"file": [
(open("data/CC-Th0-MolsPerCell.csv", "rb"), "CC-Th0-MolsPerCell.csv"),
(open("data/CC-Th1-MolsPerCell.csv", "rb"), "CC-Th1-MolsPerCell.csv")
]})
response_data = json.loads(r.data)
assert "status" in response_data
assert response_data["status"] == "OK"
但是,我无法让 test_client 实际上传这两个文件。如果指定了多个文件,API 代码循环时 file_data 为空。我已经尝试了我自己的 ImmutableDict,其中包含两个 "file" 条目、一个文件元组列表、一个文件元组元组,以及我能想到的任何东西。
什么是API在Flasktest_client中指定多个文件上传?我在网上找不到这个! :(
测试客户端获取文件对象列表(由 open()
返回),所以这是我使用的测试实用程序:
def multi_file_upload(test_client, src_file_paths, dest_folder):
files = []
try:
files = [open(fpath, 'rb') for fpath in src_file_paths]
return test_client.post('/api/upload/', data={
'files': files,
'dest': dest_folder
})
finally:
for fp in files:
fp.close()
我认为如果您丢失元组(但保留 open()
s),那么您的代码可能会起作用。
另一种方法 - 如果你想在这里明确命名你的文件上传(我的用例是两个 CSV,但可以是任何东西)test_client 是这样的:
resp = test_client.post(
'/data_upload_api', # flask route
file_upload_one=[open(FILE_PATH, 'rb')],
file_upload_two=[open(FILE_PATH_2, 'rb')]
)
使用此语法,这些文件将可以访问为:
request.files['file_upload_one'] # etc.
您应该只发送数据对象和您想要命名的文件:
test_client.post('/api/upload',
data={'title': 'upload sample',
'file1': (io.BytesIO(b'get something'), 'file1'),
'file2': (io.BytesIO(b'forthright'), 'file2')},
content_type='multipart/form-data')