使用 IoT 中心将文件从设备上传到云 (Python)Upload files from your device to the cloud with IoT Hub (Python)

本文演示如何使用 IoT 中心的文件上传功能将文件上传到 Azure Blob 存储This article shows how to use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. 本教程介绍如何:The tutorial shows you how to:

  • 安全地提供存储容器用于文件上传。Securely provide a storage container for uploading a file.
  • 使用 Python 客户端通过 IoT 中心上传文件。Use the Python client to upload a file through your IoT hub.

从设备将遥测数据发送到 IoT 中心快速入门演示了 IoT 中心基本的设备到云的消息传送功能。The Send telemetry from a device to an IoT hub quickstart demonstrates the basic device-to-cloud messaging functionality of IoT Hub. 但是,在某些情况下,无法轻松地将设备发送的数据映射为 IoT 中心接受的相对较小的设备到云消息。However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub accepts. 需要从设备上传文件时,仍可以使用 IoT 中心的安全性和可靠性。When you need to upland files from a device, you can still use the security and reliability of IoT Hub.

在本教程的末尾,你将运行 Python 控制台应用:At the end of this tutorial, you run the Python console app:

  • FileUpload.py,该应用使用 Python 设备 SDK 将文件上传到存储中 。FileUpload.py, which uploads a file to storage using the Python Device SDK.

备注

IoT 中心通过 Azure IoT 设备 SDK 为许多设备平台和语言(包括 C、Java、Javascript 和 Python)提供 SDK 支持。IoT Hub has SDK support for many device platforms and languages (including C, Java, Javascript, and Python) through Azure IoT device SDKs. 有关如何使用 Python 将设备连接到本教程的代码,以及通常如何连接到 Azure IoT 中心的说明,请参阅 Azure IoT Python SDKFor instructions on how to use Python to connect your device to this tutorial's code, and generally to Azure IoT Hub, see the Azure IoT Python SDK.

先决条件Prerequisites

  • 有效的 Azure 帐户。An active Azure account. (如果没有帐户,只需几分钟即可创建一个试用帐户。)(If you don't have an account, you can create a trial account in just a couple of minutes.)

  • 建议使用 Python 3.7.2 或更高版本Python version 3.7 or later is recommended. 请确保根据安装程序的要求,使用 32 位或 64 位安装。Make sure to use the 32-bit or 64-bit installation as required by your setup. 在安装过程中出现提示时,请确保将 Python 添加到特定于平台的环境变量中。When prompted during the installation, make sure to add Python to your platform-specific environment variable. 有关支持的其他 Python 版本,请参阅 SDK 文档中的 Azure IoT 设备功能For other versions of Python supported, see Azure IoT Device Features in the SDK documentation.

    重要

    由于本文中的设备代码使用异步 API,因此不能使用 Python 2.7。Because the device code in this article uses the asynchronous API, you cannot use Python 2.7.

  • 确保已在防火墙中打开端口 8883。Make sure that port 8883 is open in your firewall. 本文中的设备示例使用 MQTT 协议,该协议通过端口 8883 进行通信。The device sample in this article uses MQTT protocol, which communicates over port 8883. 在某些公司和教育网络环境中,此端口可能被阻止。This port may be blocked in some corporate and educational network environments. 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).

将 Azure 存储帐户关联到 IoT 中心Associate an Azure Storage account to IoT Hub

由于模拟设备应用将文件上传到 Blob,因此必须拥有与 IoT 中心关联的 Azure 存储帐户。Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated with your IoT hub. 将 Azure 存储帐户与 IoT 中心相关联时,IoT 中心会生成一个 SAS URI。When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. 设备可以使用此 SAS URI 安全地将文件上传到 Blob 容器。A device can use this SAS URI to securely upload a file to a blob container. IoT 中心服务和设备 SDK 协调生成 SAS URI 的过程,并使其可供设备用来上传文件。The IoT Hub service and the device SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.

按照使用 Azure 门户配置文件上传中的说明进行操作。Follow the instructions in Configure file uploads using the Azure portal. 确保有一个 Blob 容器与 IoT 中心关联并且已启用文件通知。Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.

在门户中启用文件通知

从设备应用上传文件Upload a file from a device app

本部分中操作将会创建可将文件上传到 IoT 中心的设备应用。In this section, you create the device app to upload a file to IoT hub.

  1. 在命令提示符处,运行以下命令来安装 azure-iot-device 包。At your command prompt, run the following command to install the azure-iot-device package. 可以使用此包与 IoT 中心协调文件上传操作。You use this package to coordinate the file upload with your IoT hub.

    pip install azure-iot-device
    
  2. 在命令提示符处,运行以下命令来安装 azure.storage.blob 包。At your command prompt, run the following command to install the azure.storage.blob package. 可以使用此包执行文件上传操作。You use this package to perform the file upload.

    pip install azure.storage.blob
    
  3. 创建将上传到 blob 存储的测试文件。Create a test file that you'll upload to blob storage.

  4. 使用文本编辑器,在工作文件夹中创建一个 FileUpload.py 文件 。Using a text editor, create a FileUpload.py file in your working folder.

  5. 在 FileUpload.py 文件的开头添加以下 import 语句和变量 。Add the following import statements and variables at the start of the FileUpload.py file.

    import os
    import asyncio
    from azure.iot.device.aio import IoTHubDeviceClient
    from azure.core.exceptions import AzureError
    from azure.storage.blob import BlobClient
    
    CONNECTION_STRING = "[Device Connection String]"
    PATH_TO_FILE = r"[Full path to local file]"
    
  6. 在文件中,将 [Device Connection String] 替换为 IoT 中心设备的连接字符串。In your file, replace [Device Connection String] with the connection string of your IoT hub device. [Full path to local file] 替换为你创建的测试文件的路径,或是设备上要上传的任何文件的路径。Replace [Full path to local file] with the path to the test file that you created or any file on your device that you want to upload.

  7. 创建一个函数以将文件上传到 blob 存储:Create a function to upload the file to blob storage:

    async def store_blob(blob_info, file_name):
        try:
            sas_url = "https://{}/{}/{}{}".format(
                blob_info["hostName"],
                blob_info["containerName"],
                blob_info["blobName"],
                blob_info["sasToken"]
            )
    
            print("\nUploading file: {} to Azure Storage as blob: {} in container {}\n".format(file_name, blob_info["blobName"], blob_info["containerName"]))
    
            # Upload the specified file
            with BlobClient.from_blob_url(sas_url) as blob_client:
                with open(file_name, "rb") as f:
                    result = blob_client.upload_blob(f, overwrite=True)
                    return (True, result)
    
        except FileNotFoundError as ex:
            # catch file not found and add an HTTP status code to return in notification to IoT Hub
            ex.status_code = 404
            return (False, ex)
    
        except AzureError as ex:
            # catch Azure errors that might result from the upload operation
            return (False, ex)
    

    此函数分析传递给它的 blob_info 结构,以创建用于初始化 azure.storage.blob.BlobClient 的 URL。This function parses the blob_info structure passed into it to create a URL that it uses to initialize an azure.storage.blob.BlobClient. 然后,它使用此客户端将文件上传到 Azure Blob 存储。Then it uploads your file to Azure blob storage using this client.

  8. 添加下述用来连接客户端并上传文件的代码:Add the following code to connect the client and upload the file:

    async def main():
        try:
            print ( "IoT Hub file upload sample, press Ctrl-C to exit" )
    
            conn_str = CONNECTION_STRING
            file_name = PATH_TO_FILE
            blob_name = os.path.basename(file_name)
    
            device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
    
            # Connect the client
            await device_client.connect()
    
            # Get the storage info for the blob
            storage_info = await device_client.get_storage_info_for_blob(blob_name)
    
            # Upload to blob
            success, result = await store_blob(storage_info, file_name)
    
            if success == True:
                print("Upload succeeded. Result is: \n") 
                print(result)
                print()
    
                await device_client.notify_blob_upload_status(
                    storage_info["correlationId"], True, 200, "OK: {}".format(file_name)
                )
    
            else :
                # If the upload was not successful, the result is the exception object
                print("Upload failed. Exception is: \n") 
                print(result)
                print()
    
                await device_client.notify_blob_upload_status(
                    storage_info["correlationId"], False, result.status_code, str(result)
                )
    
        except Exception as ex:
            print("\nException:")
            print(ex)
    
        except KeyboardInterrupt:
            print ( "\nIoTHubDeviceClient sample stopped" )
    
        finally:
            # Finally, disconnect the client
            await device_client.disconnect()
    
    
    if __name__ == "__main__":
        asyncio.run(main())
        #loop = asyncio.get_event_loop()
        #loop.run_until_complete(main())
        #loop.close()
    

    此代码创建一个异步的 IoTHubDeviceClient ,并使用以下 API 来管理通过 IoT 中心进行的文件上传操作:This code creates an asynchronous IoTHubDeviceClient and uses the following APIs to manage the file upload with your IoT hub:

    • get_storage_info_for_blob 从 IoT 中心获取你之前创建的链接存储帐户的相关信息。get_storage_info_for_blob gets information from your IoT hub about the linked Storage Account you created previously. 此信息包括主机名、容器名称、blob 名称和 SAS 令牌。This information includes the hostname, container name, blob name, and a SAS token. 存储信息传递到 store_blob 函数(在上一步中创建),因此该函数中的 BlobClient 可以通过 Azure 存储进行身份验证。The storage info is passed to the store_blob function (created in the previous step), so the BlobClient in that function can authenticate with Azure storage. get_storage_info_for_blob 方法还会返回一个 correlation_id,后者在 notify_blob_upload_status 方法中使用。The get_storage_info_for_blob method also returns a correlation_id, which is used in the notify_blob_upload_status method. IoT 中心使用 correlation_id 来标记你在处理的 blob。The correlation_id is IoT Hub's way of marking which blob you're working on.

    • notify_blob_upload_status 向 IoT 中心通知你的 blob 存储操作的状态。notify_blob_upload_status notifies IoT Hub of the status of your blob storage operation. 你将向其传递通过 get_storage_info_for_blob 方法获取的 correlation_id。You pass it the correlation_id obtained by the get_storage_info_for_blob method. IoT 中心使用它来通知任何可能正在侦听文件上传任务状态通知的服务。It's used by IoT Hub to notify any service that might be listening for a notification on the status of the file upload task.

  9. 保存并关闭 UploadFile.py 文件 。Save and close the UploadFile.py file.

运行应用程序Run the application

现即可运行应用程序。Now you are ready to run the application.

  1. 在工作文件夹的命令提示符处,运行以下命令:At a command prompt in your working folder, run the following command:

    python FileUpload.py
    
  2. 以下屏幕截图显示来自 FileUpload 应用的输出 :The following screenshot shows the output from the FileUpload app:

    simulated-device 应用的输出

  3. 可以使用门户查看所配置的存储容器中上传的文件:You can use the portal to view the uploaded file in the storage container you configured:

    上传的文件

后续步骤Next steps

在本教程中,已学习了如何使用 IoT 中心的文件上传功能来简化从设备进行的文件上传。In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices. 可以使用以下文章继续探索 IoT 中心功能和方案:You can continue to explore IoT hub features and scenarios with the following articles:

使用以下链接详细了解 Azure Blob 存储:Learn more about Azure Blob Storage with the following links: