
Azure Functions 输出绑定深入探究在 IoT-For-Beginners 交通项目中用 Blob 存储输出绑定保存 GPS 数据【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇文章是 IoT-For-Beginners 课程3-transport/lessons/2-store-location-data存储位置数据一课课后作业assignment.md的深入展开。该作业的核心任务是理解 Azure Functions 的触发器和绑定机制掌握通过function.json配置Blob 存储输出绑定Blob storage output binding让函数代码只需从main函数返回 blob 即可自动写入 Azure Blob 存储。读完本文你将掌握函数绑定trigger / input / output的基础概念、function.json的配置语法、输出绑定与 Python SDK 两种写入存储方案的取舍并能对照本仓库内的完整代码完成自己的绑定配置实验。一、作业背景为什么需要函数绑定在上一课中GPS 传感器采集到的经纬度数据被发送到 Azure IoT Hub。为了在下一课中把这些数据绘制到地图上这些遥测事件需要被服务端代码接住并持久化——这正是本课 warm path温路径 数据流的一部分数据到达云端后先落盘存储供短期报告和分析使用。在 3-transport/lessons/2-store-location-data/README.md 中官方给出了两条连接存储的路线在函数代码内部用 Blob 存储 Python SDK 连接存储账户并把数据写成 blob使用输出函数绑定output function binding把函数的返回值绑定到 Blob 存储由运行时自动保存。本课正文采用了第 1 种Python SDK方案而本次作业要求你自行研究第 2 种方案——读懂 Azure Functions 官方文档中关于 Triggers and Bindings 与 Blob storage output binding 的说明弄清楚如何配置输出绑定并把它实际跑通。这是一种典型的 课堂给方案、作业考原理 的设计能理解绑定的声明式配置才真正理解 Azure Functions 的运行模型。二、什么是 Azure Functions 的触发器和绑定Azure Functions 的绑定模型把函数与外部服务的数据交互从代码中抽离出来声明式地放在配置文件里。绑定分为三类Trigger触发器定义函数被调用的时机是函数的入口事件源。一个函数有且只有一个触发器。Input binding输入绑定为函数提供额外的只读数据输入。Output binding输出绑定把函数的结果如返回值自动写入目标服务无需在代码里手写连接逻辑。在本仓库的函数项目中main函数的入口正是一个 Event Hub 触发器声明在 function.json 中{ scriptFile: __init__.py, bindings: [ { type: eventHubTrigger, name: events, direction: in, eventHubName: samples-workitems, connection: IOT_HUB_CONNECTION_STRING, cardinality: many, consumerGroup: $Default, dataType: binary } ] }字段含义拆解字段作用type绑定类型这里是eventHubTriggerEvent Hub 兼容端点触发器name绑定在代码中的参数名events对应main(events: List[func.EventHubEvent])的入参direction数据方向in表示输入/触发器eventHubNameEvent Hub 名称示例值为占位符samples-workitemsconnection存放连接字符串的环境变量名指向local.settings.json或云上 Application Settings 中的IOT_HUB_CONNECTION_STRINGcardinalitymany表示批量接收事件对应List[func.EventHubEvent]one表示单条consumerGroup消费组默认$DefaultdataType数据类型binary表示以二进制传入关键点在于触发器只负责把事件送进函数事件落盘存储则需要在bindings数组中追加一个方向为out的绑定条目。这正是作业要求你研究的内容。三、function.json中声明 Blob 存储输出绑定Azure Functions 的绑定配置遵循统一模型输出绑定与输入绑定同处一个bindings数组只需满足三点type设为 Blob 存储相关类型对 Python v2 之前的 v1/v2 模型为blobdirection设为outname与代码中main函数的参数名一致。一个典型的 Blob 输出绑定条目如下结合本作业任务与 官方输出绑定文档 的说明整理供你对照自己的实现{ type: blob, name: outputBlob, direction: out, path: gps-data/{deviceId}/{rand-guid}.json, connection: STORAGE_CONNECTION_STRING }pathblob 的容器与文件名模板。这里的{deviceId}来自函数签名中的绑定表达式binding expression{rand-guid}是系统提供的随机 GUID——无需自己用uuid生成文件名运行时自动展开。connection存储账户连接字符串所在的环境变量名本仓库中即STORAGE_CONNECTION_STRING见 local.settings.json。配置完成后在__init__.py的main函数签名中加入同名参数函数return一个字节串或字符串即可自动写入 blobimport azure.functions as func def main(events: func.EventHubEvent, outputBlob: func.Out[str]): body events.get_body().decode(utf-8) # 把结果通过输出绑定写回 blob 存储 outputBlob.set(json.dumps({gps: json.loads(body)[gps]}))如果采用返回值绑定的写法不使用func.Out参数而是直接 return则函数返回的内容会按path写入存储返回None时不会产生任何写入。这正是作业描述中通过从main函数返回 blob 来保存到 blob 存储的含义。四、两种写入方案在仓库中的实际对照为了帮助你完成作业可以对比本仓库已经实现好的SDK 方案课堂正文路线它就是你实现输出绑定方案时的参照物。4.1 SDK 方案手写连接与上传仓库的 iot-hub-trigger/init.py 完整实现了用 Python SDK 写 blobdef get_or_create_container(name): connection_str os.environ[STORAGE_CONNECTION_STRING] blob_service_client BlobServiceClient.from_connection_string(connection_str) for container in blob_service_client.list_containers(): if container.name name: return blob_service_client.get_container_client(container.name) return blob_service_client.create_container(name, public_accessPublicAccess.Container) def main(events: List[func.EventHubEvent]): for event in events: logging.info(Python EventHub trigger processed an event: %s, event.get_body().decode(utf-8)) device_id event.iothub_metadata[connection-device-id] blob_name f{device_id}/{str(uuid.uuid1())}.json container_client get_or_create_container(gps-data) blob container_client.get_blob_client(blob_name) event_body json.loads(event.get_body().decode(utf-8)) blob_body { device_id : device_id, timestamp : event.iothub_metadata[enqueuedtime], gps: event_body[gps] } logging.info(fWriting blob to {blob_name} - {blob_body}) blob.upload_blob(json.dumps(blob_body).encode(utf-8))这套代码里能看到 SDK 方案的全部细节连接串从os.environ[STORAGE_CONNECTION_STRING]读取本地开发时由 local.settings.json 注入云端部署后由 Application Settings 注入容器不存在时自动创建get_or_create_container先遍历list_containers()找不到再create_container(..., public_accessPublicAccess.Container)。给容器开放公共访问权限是为了下一课在地图上可视化 GPS 数据时可以直接查询blob 名按设备分文件夹f{device_id}/{str(uuid.uuid1())}.json例如gps-sensor/a9487ac2-b9cf-11eb-b5cd-1e00621e3648.jsonblob 内容结构为{device_id: ..., timestamp: 入队时间, gps: {lat: ..., lon: ...}}。特别地时间戳取event.iothub_metadata[enqueuedtime]消息入队时间而非当前时间——如果 Functions 应用未运行消息可能在 Hub 上滞留一段时间用入队时间才能还原真实发送时刻。4.2 输出绑定方案声明式自动写入对照之下输出绑定方案的目标是删掉上面这段样板代码不再 importBlobServiceClient、不再管理连接串、不再手工upload_blob只需在function.json里加一个out绑定并在函数签名/返回值中暴露该绑定。两者的能力对比如下维度Python SDK 方案本课正文输出绑定方案本次作业连接管理代码中从环境变量读取并创建客户端运行时根据connection字段自动处理容器创建需手写get_or_create_container需预先创建容器或依赖绑定路径blob 命名代码中用uuid拼路径绑定path模板 {rand-guid}表达式代码侵入高需要存储相关 import 与异常处理低只关心业务数据组装灵活性高可自由控制容器/权限/批量逻辑较低按声明模板写入五、本地开发环境的配套配置无论走哪条路线本地开发都依赖同一个配置骨架值得一并掌握local.settings.json本地密钥与运行时配置FUNCTIONS_WORKER_RUNTIME为pythonAzureWebJobsStorage使用UseDevelopmentStoragetrue指向 Azurite 本地存储模拟器IOT_HUB_CONNECTION_STRING与STORAGE_CONNECTION_STRING分别供给触发器和存储绑定使用host.jsonFunctions 宿主配置版本2.0并通过extensionBundle引入Microsoft.Azure.Functions.ExtensionBundle[2.*, 3.0.0)绑定扩展无需单独安装 NuGet 包——这正是绑定声明式配置得以简化运行成本的关键requirements.txtPython 依赖清单注意注释明确提醒不要包含azure-functions-worker会与 Functions 平台冲突只需azure-functions与azure-storage-blob。六、作业验收标准与自查清单作业 assignment.md 给出的评估标准Rubric是一张单维度表格围绕是否成功配置 Blob 存储输出绑定分级标准优秀Exemplary合格Adequate需改进Needs Improvement配置 Blob 存储输出绑定能配置输出绑定、返回 blob且 blob 成功写入存储能配置输出绑定、或能返回 blob但未能成功写入存储完全无法配置输出绑定对照此标准完成作业时可按下述步骤自查确认绑定声明正确function.json的bindings数组中包含type: blob、direction: out的条目且path指向gps-data容器确认连接串生效local.settings.json中STORAGE_CONNECTION_STRING的值来自az storage account show-connection-string --output table --name storage_name命令的输出函数签名与function.json的name字段一致确认返回值被写入运行 Functions 应用的同时让虚拟设备code/virtual-device/gps-sensor/app.py持续发送 GPS 遥测JSON 格式为{gps: {lat: ..., lon: ...}}然后用az storage blob list --container-name gps-data --output table --account-name storage_name --account-key key1检查容器中是否出现新 blob并用az storage blob download下载校验内容注意调试陷阱运行 Functions 应用时不要同时运行az iot hub monitor-events抢占 Event Hub 消费输出绑定模式下若返回None则不会写入任何 blob这是最常见的配置正确却无数据原因。七、结语本次作业的价值在于把数据如何从 IoT Hub 流到 Blob 存储这件事从调用代码提升到声明配置的认知层次。function.json中的每个绑定条目都是一种契约触发器声明数据从哪里来输出绑定声明数据到哪里去。你在 3-transport/lessons/2-store-location-data/README.md 中已经看到了 SDK 路线的完整实现而作业要你独立走通输出绑定路线——两条路线殊途同归最终都服务于下一课在地图上可视化车辆轨迹的 warm path 数据流。提示本作业涉及的微软官方文档Azure Functions 触发器与绑定概念、Blob 存储绑定概览、Blob 存储输出绑定建议直接访问微软文档站点阅读注意其中的 Python 版本标签页与绑定属性参考。本文档源自课程翻译版本作业原文以 3-transport/lessons/2-store-location-data/assignment.md 为准。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考