我应该如何修改下面的代码(取自这篇文章),使文件是而不是保存到磁盘,但是保存到内存而不是?该代码使用streaming-form-data
库解析multipart/form-data
输入块。
不幸的是,下面的代码目前需要一个路径,我想阻止这样的I/O操作。
from fastapi import FastAPI, Request, status
from fastapi.exceptions import HTTPException
from streaming_form_data import StreamingFormDataParser
from streaming_form_data.targets import FileTarget, ValueTarget
from streaming_form_data.validators import MaxSizeValidator
import streaming_form_data
from starlette.requests import ClientDisconnect
import os
MAX_FILE_SIZE = 1024 * 1024 * 1024 * 4 # = 4GB
MAX_REQUEST_BODY_SIZE = MAX_FILE_SIZE + 1024
app = FastAPI()
class MaxBodySizeException(Exception):
def __init__(self, body_len: str):
self.body_len = body_len
class MaxBodySizeValidator:
def __init__(self, max_size: int):
self.body_len = 0
self.max_size = max_size
def __call__(self, chunk: bytes):
self.body_len += len(chunk)
if self.body_len > self.max_size:
raise MaxBodySizeException(body_len=self.body_len)
@app.post('/upload')
async def upload(request: Request):
body_validator = MaxBodySizeValidator(MAX_REQUEST_BODY_SIZE)
filename = request.headers.get('Filename')
if not filename:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail='Filename header is missing')
try:
filepath = os.path.join('./', os.path.basename(filename))
file_ = FileTarget(filepath, validator=MaxSizeValidator(MAX_FILE_SIZE))
data = ValueTarget()
parser = StreamingFormDataParser(headers=request.headers)
parser.register('file', file_)
parser.register('data', data)
async for chunk in request.stream():
body_validator(chunk)
parser.data_received(chunk)
(...)
解决方案已经在给出了答案(演示"如何上传一个大文件(≥3GB)到FastAPI后端"),你从中获取了代码。如果您希望将数据保存在内存中,而不是将它们写入磁盘,那么您只需要使用ValueTarget
而不是FileTarget
对象。例如:
file_ = ValueTarget(validator=MaxSizeValidator(MAX_FILE_SIZE))
要获取文件内容,可以使用.value
属性,例如:
print(file_.value)