mar*_*lli 4 azure python-3.x azure-functions serverless
我在 Azure 上创建了一个带有 HTTP 触发器的云函数,我希望能够使用表单处理文件上传。
我的入口点是这样的:
def main(req: func.HttpRequest) -> func.HttpResponse:
body = req.get_body()
headers=req.headers
...
Run Code Online (Sandbox Code Playgroud)
问题是我得到的body是原始二进制文件,我不知道如何解码它并获取上传的文件。
有谁知道实现这一目标的好方法?
我想说,有一种 Azure 本地方式可以做到这一点,还有一种 Python 本地方式。
azure.functions.HttpRequest有一个files属性是MultiDict生成器。以下是如何使用它:
import logging
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
for input_file in req.files.values():
filename = input_file.filename
contents = input_file.stream.read()
logging.info('Filename: %s' % filename)
logging.info('Contents:')
logging.info(contents)
[..process the file here as you want..]
return func.HttpResponse(f'Done\n')
Run Code Online (Sandbox Code Playgroud)
如果您只想使用标准的 Python 库(例如为了更多的可移植性),那么您应该知道您需要在正文中解析的是MIME 多部分消息,以二进制形式:
Content-Type: multipart/form-data; boundary=--------------------------1715cbf149d89cd9
--------------------------1715cbf149d89cd9
Content-Disposition: form-data; name="data"; filename="test.txt"
Content-Type: application/octet-stream
this is a test document
--------------------------1715cbf149d89cd9--
Run Code Online (Sandbox Code Playgroud)
要重现的示例脚本:
echo 'this is a test document' > test.txt && curl -F 'data=@test.txt' 'https://[..yourfunctionname..].azurewebsites.net/api/HttpTrigger'
Run Code Online (Sandbox Code Playgroud)
您会感到惊讶,但该email模块会为您做到这一点(我个人认为它的名字很糟糕)。
下面的示例代码(注意:没有错误处理!)以突出核心思想:
import cgi
import email
import logging
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
# Content-Type should be 'multipart/form-data' with some boundary
content_type = req.headers.get('Content-Type')
body = req.get_body().decode('utf-8')
mime_template = 'MIME-Version: 1.0\nContent-Type: %s\n%s'
post_data = email.parser.Parser().parsestr(mime_template % (content_type, body))
# Content-Disposition header format:
# 'form-data; name="data"; filename="test.txt"'
disposition = post_data.get_payload()[0]['Content-Disposition']
disposition_value = cgi.parse_header('Content-Disposition: %s' % disposition)[1]
filename = disposition_value['filename']
contents = post_data.get_payload()[0].get_payload()
logging.info('Filename: %s' % filename)
logging.info('Contents:')
logging.info(contents)
[..process the file here as you want..]
return func.HttpResponse(f'Done\n')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1414 次 |
| 最近记录: |