Python 3.x Azure云使用Python实现HTTP文件上传
我在Azure上创建了一个带有HTTP触发器的云函数,我希望能够使用表单处理文件上载。Python 3.x Azure云使用Python实现HTTP文件上传,python-3.x,azure,azure-functions,serverless,Python 3.x,Azure,Azure Functions,Serverless,我在Azure上创建了一个带有HTTP触发器的云函数,我希望能够使用表单处理文件上载。 我的切入点如下所示: def main(req: func.HttpRequest) -> func.HttpResponse: body = req.get_body() headers=req.headers ... 问题是,我在body中得到的是原始二进制文件,我不知道如何解码并获得上传的文件 有人知道实现这一点的好方法吗?我认为最好的解决方法是将这些二进制数据转换成文件
我的切入点如下所示:
def main(req: func.HttpRequest) -> func.HttpResponse:
body = req.get_body()
headers=req.headers
...
问题是,我在body
中得到的是原始二进制文件,我不知道如何解码并获得上传的文件
有人知道实现这一点的好方法吗?我认为最好的解决方法是将这些二进制数据转换成文件,然后上传到blob存储
#upload to picture to blob storage
block_blob_service = BlockBlobService(account_name=accuntName, account_key=accuntKey)
container_name = 'machineimages'
blob_name = image_name + '.jpeg'
# Creating the blob
block_blob_service.create_blob_from_bytes(container_name, blob_name, decoded_image,
content_settings=ContentSettings(content_type='image/png'))
logging.info("Successfull blob creating ")
# Returning a succesful post request
return func.HttpResponse(f"successful request")
这里有一个我想说,有一个Azure本机方法可以做到这一点,还有一个Python本机方法 Azure本机方法
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')
Python本机方法
如果您只想使用标准Python库(例如,为了更大的可移植性),那么您应该知道,您需要在主体中解析的是二进制形式的:
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--
要复制的示例脚本:
echo 'this is a test document' > test.txt && curl -F 'data=@test.txt' 'https://[..yourfunctionname..].azurewebsites.net/api/HttpTrigger'
你会感到惊讶,但是电子邮件
模块(我个人认为它的名字不好)
下面的示例代码(注意:没有错误处理!)强调了核心思想:
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')
显然,create\u blob\u from_bytes和BlobServiceClient都不存在于我们默认获得的最新版本中 所以我不得不绕道而行
from azure.storage.blob import (
BlobServiceClient,
ContentSettings
)
# decoding base64 image from json body
decoded_image = base64.b64decode(image)
blob_service_client = BlobServiceClient.from_connection_string(
conn_str=storage_connection_string
)
logging.debug(f'getting client for container : {container_name}')
container_client =
blob_service_client.get_container_client(container=container_name)
blob_client = container_client.get_blob_client(blob_name)
if blob_client.exists():
blob_client.delete_blob()
blob_client = blob_service_client.get_blob_client(container=container_name,
blob=blob_name)
try:
blob_client.upload_blob(decoded_image)
content_settings =ContentSettings(content_type='image/png')
logging.debug(f'setting the content type : {content_settings}')
except Exception as e:
logging.error(str(e))
这对你有帮助吗?顺便说一句,你使用的是更新版本吗?如果你想要的内容,你也可以这样做