社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何通过python请求库将Starlette FormData数据结构发送到FastAPI端点

Kaiwen Looi • 3 年前 • 1460 次点击  

我的系统架构当前将一个表单数据blob从前端发送到后端,这两个表单数据blob都托管在不同端口的localhost上。表单数据通过FastAPI库在后端接收,如图所示。

@app.post('/avatar/request')
async def get_avatar_request(request: Request, Authorize: AuthJWT = Depends()):
    form = await request.form()
    return run_function_in_jwt_wrapper(get_avatar_output, form, Authorize, False)

目前,我正在尝试使用请求库将未修改的表单数据从后端转发到另一个FASTApi端点,如下所示:

response = requests.post(models_config["avatar_api"], data = form_data, headers = {"response-type": "blob"})

虽然目标端点确实接收表单数据,但它似乎没有正确解析UploadFile组件。我没有得到相应的Starlete UploadFile数据结构,而是收到了类名的字符串,如下面的错误消息所示:

FormData([('avatarFile', '<starlette.datastructures.UploadFile object at 0x7f8d25468550>'), ('avatarFileType', 'jpeg'), ('background', 'From Image'), ('voice', 'en-US-Wavenet-B'), ('transcriptKind', 'text'), ('translateToLanguage', 'No translation'), ('transcriptText', 'do')])

我该如何处理这个问题?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/130500
 
1460 次点击  
文章 [ 1 ]  |  最新文章 3 年前
Ben
Reply   •   1 楼
Ben    3 年前

FileUpload 是python对象,在使用之前需要以某种方式序列化它 requests.post() 然后对其进行反序列化,然后通过 content = await form["upload-file"].read() .我觉得你不想连载 文件上传 对象(如果可能的话),而是阅读表单数据的内容,然后发布。

更妙的是,如果您的其他FASTAPI终结点是同一服务的一部分,那么您可以考虑只调用一个函数,并完全避免请求(可能使用路由函数调用的控制器函数,以防您还需要从服务外部调用该端点,然后只需直接调用控制器函数,避免路由和请求的需要)。通过这种方式,您可以传递任何您想要的内容,而无需序列化它。

如果你必须使用请求,那么我会阅读表单的内容,然后用表单数据创建一个新帖子。例如

form = await request.form()  # starlette.datastructures.FormData
upload_file = form["upload_file"]  # starlette.datastructures.UploadFile - not used here, but just for illustrative purposes
filename = form["upload_file"].filename  # str
contents = await form["upload_file"].read()  # bytes
content_type = form["upload_file"].content_type  # str
...
data = {k: v for k, v in form.items() if k != "upload-file"} # the form data except the file
files = {"upload-file": (filename, contents, content_type)} # the file
requests.post(models_config["avatar_api"], files=files, data=data, headers = {"response-type": "blob"})