尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Azure Functions 输出绑定实战:在 IoT-For-Beginners 定位数据存储任务中配置 Blob 输出绑定
Azure Functions 输出绑定实战在 IoT-For-Beginners 定位数据存储任务中配置 Blob 输出绑定【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners导读本文围绕 IoT-For-Beginners 课程体系中存储定位数据Store location data一课的任务assignment展开深度解析 Azure Functions 的函数绑定Function Bindings机制——尤其是Blob 存储输出绑定Output Binding。在课程中GPS 传感器采集的定位遥测经 Azure IoT Hub 进入 Azure Functions本任务要求读者脱离在函数代码内用 Python SDK 手动写 Blob的路径改为在function.json中声明输出绑定、从main函数直接返回 Blob 内容让平台自动完成落盘。读完本文你将掌握触发器与输入/输出绑定的概念区分、输出绑定的声明语法与参数含义、Python 运行时下的返回值约定并能结合本仓库的真实代码完成从 SDK 写入到输出绑定写入的改造与验收。任务背景定位数据存储的两种落盘方式在课程正文 3-transport/lessons/2-store-location-data/README.md 中读者已经完成了一条完整的热路径链路用 GPS 传感器采集经纬度按{gps: {lat: 纬度, lon: 经度}}的 JSON 格式每分钟向 Azure IoT Hub 发送一次遥测创建一个 Python 运行时Runtime的 Azure Functions 应用gps-trigger并通过eventHubTrigger监听 IoT Hub 的 Event Hub 兼容终结点将遥测数据作为 JSON 写入 Azure Storage 账户的 Blob 容器为下一课的路径可视化做准备。课程正文明确指出了连接函数应用与 Blob 存储的两种方式方式一课程正文采用在函数代码内部使用 Blob 存储的 Python SDKazure-storage-blob主动创建容器客户端并上传 Blob方式二本任务要求研究使用输出函数绑定output function binding将函数的返回值绑定到 Blob 存储由运行时自动把返回内容保存为 Blob。本任务正是要求读者深入研究第二种方式。任务原文位于 3-transport/lessons/2-store-location-data/assignment.md其核心论断是函数绑定Function Bindings使你的代码能够通过从main函数返回内容将 Blob 保存到 Blob 存储中。Azure 存储账户、集合容器及其他细节均在function.json文件中配置。也就是说与在代码里手写上传逻辑相比输出绑定把存储账户是谁、写到哪个容器、文件放在什么路径这些细节全部声明式地下沉到function.json函数体只负责返回数据。这也是理解 Azure Functions以声明代替命令这一设计哲学的关键切入点。理解 Azure Functions 绑定触发器、输入绑定与输出绑定Azure Functions 的绑定Bindings是一种将函数与外部服务存储、队列、事件中心、HTTP 等声明式连接的机制。函数不需要关心底层 SDK 的连接管理只需在function.json中描述数据从哪来、到哪去运行时即负责建立连接、序列化与调用。按数据流向绑定分为三类绑定类型direction 值作用触发器Triggerin特殊决定函数何时被调用例如eventHubTrigger、queueTrigger、httpTrigger输入绑定Input Bindingin在函数执行前由运行时注入只读数据例如读取指定路径的 Blob 内容作为入参输出绑定Output Bindingout在函数执行结束后将函数的返回值或通过func.Out写入的变量持久化到目标服务例如写入 Blob、写队列消息在 Python 运行时中一次函数调用对应function.json中bindings数组里的一组声明数组内的每个对象描述一个绑定type指定服务类型如eventHubTrigger、blobdirection指定方向in/outname指定在 Python 函数签名中该数据以什么参数名暴露。本任务要求研究的正是在已有eventHubTrigger输入绑定的基础上新增一个blob类型的输出绑定让函数返回值自动写入 Blob 存储。仓库现状事件触发器与 SDK 手动写入在动手配置输出绑定之前先看本仓库中该函数应用的实际配置与代码它们是理解输出绑定能省掉什么的最佳对照。function.json只声明了触发器当前 iot-hub-trigger/function.json 中只有一个eventHubTrigger输入绑定{ scriptFile: __init__.py, bindings: [ { type: eventHubTrigger, name: events, direction: in, eventHubName: samples-workitems, connection: IOT_HUB_CONNECTION_STRING, cardinality: many, consumerGroup: $Default, dataType: binary } ] }各字段含义如下scriptFile入口 Python 文件__init__.pytype绑定类型eventHubTrigger表示由 IoT Hub / Event Hub 的兼容终结点触发name触发器数据注入到函数签名时的参数名本例为events对应def main(events: List[func.EventHubEvent])direction数据流方向in表示进入函数eventHubName要监听的 Event Hub 名称connection存放连接字符串的配置项名称值本身放在local.settings.json或云端的 Application Settings 中键名为IOT_HUB_CONNECTION_STRINGcardinalitymany表示一次调用可以批量处理多个事件对应参数类型List[func.EventHubEvent]consumerGroup消费者组默认$DefaultdataTypebinary表示以二进制形式传递事件体。注意一个易混淆点这里的connection字段存放的不是连接字符串本身而是指向配置项名字的间接引用——运行时会在环境变量本地为local.settings.json的Values段云端为 Application Settings中查找同名键。这一约定同样适用于稍后要配置的 Blob 输出绑定。init.py当前使用 Python SDK 手动上传init.py 展示了方式一的完整实现。核心逻辑可拆为四步① 读取连接字符串并获取/创建容器第 10–18 行的get_or_create_containerdef 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)由于 Python Blob SDK 没有不存在则创建的现成方法这段代码先遍历现有容器查找目标容器找不到就创建并授予PublicAccess.Container公共读权限供下一课在地图上直接可视化 GPS 数据。② 构造 Blob 名称第 25–26 行device_id event.iothub_metadata[connection-device-id] blob_name f{device_id}/{str(uuid.uuid1())}.json从事件元数据中取设备 ID 作为文件夹再以uuid.uuid1()生成的唯一 ID 作为文件名形成如gps-sensor/a9487ac2-b9cf-11eb-b5cd-1e00621e3648.json的 Blob 路径。③ 组装 JSON 文档体第 31–36 行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] }特意使用消息的**入队时间enqueuedtime**而非当前时间避免函数应用未运行时消息在 Hub 上滞留导致时间失真。④ 上传第 38–39 行logging.info(fWriting blob to {blob_name} - {blob_body}) blob.upload_blob(json.dumps(blob_body).encode(utf-8))可以看到这份代码把连接、找容器、建路径、起文件名、上传全部写进了函数体。而输出绑定要做的正是把②③④这三步尤其是建路径、起文件名与上传从代码中抽离出来交给运行时声明式完成。与之配套的配置还包括local.settings.json本地运行时环境变量Values段中已有IOT_HUB_CONNECTION_STRING与STORAGE_CONNECTION_STRING两个占位键后者正是 SDK 方式读取的存储账户连接字符串requirements.txt声明azure-functions与azure-storage-blob两个依赖注释提醒不要包含azure-functions-worker以免与 Functions 平台冲突host.jsonFunctions 主机级配置extensionBundle指定Microsoft.Azure.Functions.ExtensionBundle的[2.*, 3.0.0)版本区间。配置 Blob 存储输出绑定function.json 声明式改造根据任务要求输出绑定的存储账户、容器集合与其他细节全部在function.json中配置。参考 Azure Functions 的 Blob 输出绑定规范本任务要求自行查阅的文档主题涉及触发器与绑定概念Blob 存储绑定概述Blob 存储输出绑定三类资料一个典型的配置是在现有bindings数组中追加一个blob输出绑定{ 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: blob, name: outputblob, direction: out, path: gps-data/{deviceId}/{rand-guid}.json, connection: STORAGE_CONNECTION_STRING } ] }新增绑定各字段的含义字段取值说明typeblob绑定类型为 Azure Blob 存储nameoutputblob绑定在函数签名中暴露的标识若希望以返回值形式绑定则需命名为$returndirectionout输出绑定函数结束后由运行时写入pathgps-data/表达式.json目标容器与 Blob 路径。gps-data为容器名之后为目录/文件名可用绑定表达式动态生成connectionSTORAGE_CONNECTION_STRING存储账户连接字符串所在配置项的名称间接引用与触发器相同其中path支持的绑定表达式Binding Expressions是实现按设备分文件夹 唯一文件名的关键可参考的表达式包括触发器载荷/元数据字段例如事件中的设备 ID{rand-guid}每次执行生成一个新的 GUID保证文件名唯一对标仓库代码中的uuid.uuid1(){DateTime}、{Date}、{Time}等时间表达式可用于按时间归档。换言之仓库 SDK 代码中设备 ID 作文件夹、UUID 作文件名的逻辑在输出绑定方案里被等价地表达成了path中的绑定表达式——这正是任务标题Investigating function bindings研究函数绑定希望读者体会到的能力。注意path表达式的可用变量取决于触发器的类型与事件属性。eventHubTrigger下具体可用的绑定表达式字段正是本任务要求读者查阅 Azure Functions 官方文档触发器与绑定概念、Blob 存储绑定概述、Blob 输出绑定三页去核实的要点之一在动手前务必以目标文档的最新规范为准确认变量名大小写与可用性。改造函数代码返回 Blob 内容完成function.json的声明后函数代码需要与绑定声明对齐。Azure Functions Python 运行时支持两种输出绑定写入方式方式 A绑定名为$return直接返回内容若将输出绑定的name设为$return则main函数的返回值即为要写入 Blob 的字节内容。此时函数可改写为每收到一个事件返回一个编码后的 JSON 字节串例如def main(events: List[func.EventHubEvent]) - bytes: for event in events: event_body json.loads(event.get_body().decode(utf-8)) # 组装与仓库 SDK 版本等价的 JSON 文档体 blob_body { device_id: event.iothub_metadata[connection-device-id], timestamp: event.iothub_metadata[enqueuedtime], gps: event_body[gps] } # 返回的内容由运行时写入 path 指定的 Blob return json.dumps(blob_body).encode(utf-8)方式 B绑定名为普通标识符使用func.Out参数若绑定名为outputblob之类则函数签名中对应参数类型为func.Out[str]或func.Out[bytes]在函数体内调用其.set(...)方法完成写入def main(events: List[func.EventHubEvent], outputblob: func.Out[bytes]): for event in events: ... outputblob.set(json.dumps(blob_body).encode(utf-8))两种方式下原本需要显式创建的BlobServiceClient、get_or_create_container容器查找逻辑、uuid文件名生成与upload_blob上传调用全部由运行时接管。改造后init.py 中第 6–7 行的os、uuid导入以及第 8 行的azure.storage.blob导入除仍需要 JSON 序列化外都可以随之精简代码的关注点从如何连接存储收敛为业务数据是什么。连接字符串与运行前提无论采用哪种写入方式输出绑定都依赖连接字符串的间接引用机制在 local.settings.json 的Values段中确认存在STORAGE_CONNECTION_STRING键其值为存储账户连接字符串可用az storage account show-connection-string --output table --name storage_name获取function.json中connection字段只需写键名STORAGE_CONNECTION_STRING运行时自动解析部署到云端后同样的键名需要以 Application Settings 形式上传本任务可参考前一课程 2-farm/lessons/5-migrate-application-to-the-cloud/README.md 中的上传步骤本地与云端的配置形态完全对齐。运行前提还包括本地调试时建议使用 Azurite 作为存储模拟器课程正文中已有交代并确保 IoT Hub 事件监视器az iot hub monitor-events与函数应用不要同时运行避免消息被消费竞争导致丢失依赖清单 requirements.txt 可保持不变azure-functions即提供func.Out类型若不再使用 SDK 也可移除azure-storage-blob但保留无害。验证与验收标准完成改造后验证路径与课程正文中的 SDK 方案一致启动设备端代码持续发送 GPS 遥测运行函数应用观察日志确认事件被触发处理用az storage blob list --container-name gps-data --output table --account-name storage_name --account-key key1列出容器中的 Blob确认按设备 ID 目录自动生成了.json文件用az storage blob download --container-name gps-data --account-name storage_name --account-key key1 --name blob_name --file file_name下载并用 VS Code 打开核对 JSON 内容包含device_id、timestamp与gps三组字段。本任务原文还给出了明确的评分准则Rubric可作为验收清单评价标准优秀Exemplary合格Adequate待改进Needs Improvement配置 Blob 存储输出绑定成功配置输出绑定从函数返回 Blob且成功存储到 Blob 存储配置了输出绑定或返回了 Blob但未能成功存储到 Blob 存储无法配置输出绑定这条标准准确刻画了输出绑定方案的三个独立技术环节——声明配置function.json、返回值对接main 函数与落盘结果Blob 存储。任何一个环节脱节例如connection键名写错、绑定名与函数签名不对齐、path表达式解析失败都会使结果落入合格甚至待改进档位因此在验收时应分别验证这三者而不是只看函数是否报错。小结本任务以研究函数绑定为切入点引导读者从用 SDK 手写上传升级到用输出绑定声明落盘在function.json中追加blob/direction: out的绑定声明将存储账户、容器与路径等细节交给平台函数只需从main返回或以func.Out写入Blob 内容。结合本仓库 iot-hub-trigger 的既有实现对照可以清晰看到两种方案在关注点上的差异。掌握这一机制后你不仅能为 GPS 定位数据建立自动化的存储管线也能将同样的声明式思路迁移到队列、表存储等其他 Azure Functions 输出绑定场景中。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Slate v2 通用大文档性能架构:从 Two-Tier Auto 策略到 5000 块默认性能门禁的完整设计

Slate v2 通用大文档性能架构:从 Two-Tier Auto 策略到 5000 块默认性能门禁的完整设计

Slate v2 通用大文档性能架构:从 Two-Tier Auto 策略到 5000 块默认性能门禁的完整设计 【免费下载链接】plate Rich-text editor with AI and shadcn/ui 项目地址: https://gitcode.com/GitHub_Trending/pl/plate 导读 本文围绕 Slate v2 重写(…

📅 2026/9/17 2:30:42
基于Alpha Shapes提取有序边缘点:C++实现与算法解析

基于Alpha Shapes提取有序边缘点:C++实现与算法解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/17 2:30:42
用 gogcli 在终端创建 Google Classroom 作业:`gog classroom coursework create` 命令完全指南

用 gogcli 在终端创建 Google Classroom 作业:`gog classroom coursework create` 命令完全指南

用 gogcli 在终端创建 Google Classroom 作业:gog classroom coursework create 命令完全指南 【免费下载链接】gogcli Google Workspace in your terminal. 项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli gog classroom coursework create 是…

📅 2026/9/17 2:30:42
MORE NEWS

更多资讯

📰

远程服务器管理工具全解析:从SSH终端到Web面板的选择与实践

1. 先理清需求:你手里的服务器到底该用哪类工具远程服务器管理这事,说大不大,说小也不小。我前后管过几十台各种配置的云主机和物理机,从单机应用部署到多节点服务编排都碰过,工具换来换去,最后沉淀下来的其…

📰

2026年品牌增长密码:六大趋势与底层逻辑深度拆解

我平时不管是自己做项目,还是给朋友做品牌咨询,最常被问到的一句话就是:“现在做品牌还有机会吗?”我的回答一直很统一:越觉得没机会的时候,机会反而越是藏在一些反常识的角落里。这个“2026年值得关注的6大…

📰

MAX30102+ESP32血氧监测实战:从I²C通信到PPG信号处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

达梦8地理空间匹配适配实战:从Oracle Spatial迁移的完整复盘

上周刚把一个规划院的GIS系统从Oracle Spatial迁到达梦8,项目名称就叫“dm8 地理空间匹配适配”。听起来范围挺大,实际上就是三件事:让达梦数据库能存空间数据,能让老系统里的空间查询跑起来,再让前端GIS平台正常连上去…

📰

2026 AI论文工具TOP8实测:专科生毕业论文从开题到降重全流程指南

专科生写毕业论文,最焦虑的往往不是“写不出来”,而是“不知道从哪里开始”。尤其是年底临近、初稿截止日期压过来的时候,打开一个空白文档,光标一闪一闪,半小时敲不出两行字,这种心理压力真的比查重率还折…

📰

MySQL数据出海:跨地域同步方案选型与避坑实践

“MySQL 数据出海”,这个题目我盯了挺久。业务做到海外,服务器分散在不同区域,数据库却还窝在家里当孤岛,这种痛我太熟了。数据同步这件事,往小了说是一张订单表没同步,往大了说就是业务方天天来问“为什么…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬