【问题标题】:Can't copy/download a Blob Storage file to Azure Functions folder无法将 Blob 存储文件复制/下载到 Azure Functions 文件夹
【发布时间】:2019-11-08 18:54:11
【问题描述】:

问题详情如下:

  • 我们能够将文件上传到 Azure Blob 存储。
  • 我们还有一个 Azure 函数,它使用 http 触发器运行 Python (python 3.6) 应用程序 (engine/init.py)(该函数本质上是获取一个文件并通过 Azure 扬声器运行它识别服务)
  • 我们可以在本地机器上运行代码并且它可以工作。

问题是当我们将代码移动到 Azure 云(配置为 Linux 机器)并想要访问 Blob 存储中的文件时,应用程序无法运行(返回错误 500)。我们已经验证了路径是正确的(源和目标),我们可以在 blob 存储中看到文件,但是我们无法读取 Blob 存储中文件的内容(即我们无法读取 .txt 文件中的文本)和我们无法将文件复制或下载到 Azure Function 目录中。

文件访问详细信息位于名为 downloadFile.py 的文件中(请参见下面的代码),该文件使用 BlockBlobService 连接 Azure Blob 存储。

  • 我们使用 block_blob_service.list_blob 来查找文件
  • 我们使用 block_blob_service.get_blob_to_path 来下载文件

这两个函数在本地机器上都可以正常工作,因为我们的 requirements.txt 文件中包含 azure-storage-blob 库。

最终,我们的目标是我们需要 python 应用程序访问 Blob 存储中的文件并返回结果。我们对如何实现这一目标持开放态度。提前感谢您的帮助。

这是 requirements.txt 文件内容:

azure-functions
azure-storage-blob == 1.5.0

这是我们的代码(downloadFile.py):

from azure.storage.blob import BlockBlobService, PublicAccess
import os, uuid, sys

def run_sample():
    try:
        # Create the BlockBlockService that is used to call the Blob service for the storage account
        block_blob_service = BlockBlobService(account_name='', account_key='')
        # Create a container called 'quickstartblobs'.
        #container_name ='quickstartblobs'
        container_name ='images'
        #block_blob_service.create_container(container_name)

        # Set the permission so the blobs are public.
        #block_blob_service.set_container_acl(container_name, public_access=PublicAccess.Container)

        # Create a file in Documents to test the upload and download.

        __location__ = os.path.realpath(
        os.path.join(os.getcwd(), os.path.dirname(__file__)))
        #local_path = os.path.join(__location__, 'SoundsForJay/')
        local_path = os.path.join(__location__)
        # not able to download file to azure function.


        #local_path=os.path.abspath(os.path.curdir)

        # List the blobs in the container
        print("\nList blobs in the container")
        generator = block_blob_service.list_blobs(container_name)
        for blob in generator:
            print("\t Blob name: " + blob.name)
            if ".wav" in blob.name:
                local_file_name = blob.name

        # Download the blob(s).
        # Add '_DOWNLOADED' as prefix to '.txt' so you can see both files in Documents.

        #full_path_to_file2 = os.path.join(local_path, str.replace(local_file_name ,'.txt', '_DOWNLOADED.txt'))
        full_path_to_file2 = os.path.join(local_path, str.replace(local_file_name ,'.wav', '_DOWNLOADED.wav'))
        print("\nDownloading blob to " + full_path_to_file2)
        block_blob_service.get_blob_to_path(container_name, local_file_name, full_path_to_file2)

        sys.stdout.write("Sample finished running. When you hit <any key>, the sample will be deleted and the sample "
                         "application will exit.")
        sys.stdout.flush()
        #input()

        # Clean up resources. This includes the container and the temp files
        #block_blob_service.delete_container(container_name)
        #os.remove(full_path_to_file)
        #os.remove(full_path_to_file2)
    except Exception as e:
        print(e)
    return "run_sample is running."

【问题讨论】:

  • 您可以尝试将文件写入 /tmp 而不是当前目录吗?根据您的部署方式,当前目录可能是只读共享。
  • 能否分享一下如何查看/tmp文件夹路径以及我们如何查看/tmp文件夹的内容?我们不确定文件是否已正确下载。我们也看不到 MS Azure Storage Explorer 或 Functions App 工作区中的文件夹。谢谢!
  • @Prashant Marathay,关于这个问题的任何更新?您现在可以下载文件吗,还是您还有问题?

标签: python-3.x azure azure-functions azure-blob-storage


【解决方案1】:

现在 Python Azure 函数不允许写入文件,它是只读模式,无法更改。所以你不能使用 get_blob_to_path 因为你可以将文件写入你的磁盘。

所以如果你只是想阅读文本文件的内容,你可以使用下面的代码

filename = "test.txt"
account_name = "storage account"
account_key = "account key"

input_container_name="test"
block_blob_service = BlockBlobService(account_name, account_key)
blobstring = block_blob_service.get_blob_to_text(input_container_name, filename).content

您也可以使用函数blob binding 读取内容,将inputblob 绑定为流。

def main(req: func.HttpRequest,inputblob: func.InputStream) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')

name = req.params.get('name')
if not name:
    try:
        req_body = req.get_json()
    except ValueError:
        pass
    else:
        name = req_body.get('name')

if name:
    return func.HttpResponse(inputblob.read(size=-1))
else:
    return func.HttpResponse(
         "Please pass a name on the query string or in the request body",
         status_code=400
    )

【讨论】:

    猜你喜欢
    • 2023-01-20
    • 2021-07-29
    • 2020-01-25
    • 2020-08-18
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多