问题描述
基本上,我正在尝试创建一个终结点以将文件上载到S3
async def upload_files(filepath: str, upload_file_list: List[UploadFile] = File(...)):
for upload_file in upload_file_list:
abs_file_path = "/manual/path/works" + upload_file.path
# Replace above line to get absolute file path from UploadFile
response = s3_client.upload_file(abs_file_path,bucket_name,
os.path.join(dest_path, upload_file.filename))
上面是我将多个文件上传到S3存储桶的代码。
s3_client.upload_file()
接受要上传的文件的绝对文件路径。
当我手动输入完整路径时,它可以正常工作。
这不起作用:
response = s3_client.upload_file(upload_file.filename, bucket_name,
os.path.join(dest_path, upload_file.filename))
有没有办法在FastAPI
中获取此绝对路径?或使用temp_path
的任何替代方案,而不复制或写入文件?
如果不是,则使用boto3
将文件上载到S3的任何替代选项FastAPI
推荐答案
上传文件使用的SpooledTemporaryFile是存储在内存中的";文件,";一关闭就被销毁。您可以读取文件内容(i.e., contents = await file.read())
,然后将这些字节上传到服务器(如果允许),或者将上传文件的内容复制到NamedTemporaryFile中,如here所述。与SpooledTemporaryFile不同,NamedTemporaryFileQuot;保证在文件系统&中有一个可见的名称,可用于打开文件&Quot;。可以通过file_copy.name
contents = await file.read()
file_copy = NamedTemporaryFile('wb', delete=False)
f = None
try:
# Write the contents to the temp file
with file_copy as f:
f.write(contents);
# Here, upload the file to your S3 service
f = open(file_copy.name, 'rb')
print(f.read(10))
finally:
if f is not None:
f.close() # Remember to close the file
os.unlink(file_copy.name) # delete the file
更新
此外,还可以使用file
属性访问实际的Python文件。根据documentation:
file
:aSpooledTemporaryFile(afile-like对象)。这是实际的 可直接传递给其他函数或库的Python文件 需要类似文件的对象。
因此,您还可以尝试使用upload_fileobj
函数并传递upload_file.file
:
response = s3_client.upload_fileobj(upload_file.file, bucket_name, os.path.join(dest_path, upload_file.filename))
或者,使用SpooledTemporaryFile的_file
属性传递一个类似文件的对象,该属性返回io.BytesIO或io.TextIOWrapper对象(取决于指定的是二进制模式还是文本模式)。
response = s3_client.upload_fileobj(upload_file.file._file, bucket_name, os.path.join(dest_path, upload_file.filename))
更新2
您甚至可以将字节保存在内存缓冲区BytesIO中,使用它将内容上载到S3存储桶中,最后关闭它(调用close()
方法时,缓冲区将被丢弃。&q;)。记住在完成对BytesIO流的写入后,调用seek(0)
方法将光标重置回文件的开头。
contents = await file.read()
temp_file = io.BytesIO()
temp_file.write(contents)
temp_file.seek(0)
s3_client.upload_fileobj(temp_file, bucket_name, os.path.join(dest_path, upload_file.filename))
temp_file.close()
这篇关于如何在FastAPI中从UploadFile中获取文件路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!