本地调试Blob触发Python Azure Functions断点未命中问题
问题背景
我在main.py中编写了Blob触发的Python版Azure Functions,业务涉及两个存储账号:
- 第一个存储账号:存放图像数据与JSON数据
- 第二个存储账号:存放从第一个账号读取JSON、追加处理数据后生成的结果文件
业务代码
import logging import os import json import datetime import azure.functions as func import numpy as np from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient from msrest.authentication import ApiKeyCredentials from azure.storage.blob import BlobServiceClient from azure.cosmos import CosmosClient from os import environ from PIL import Image import requests import ast import io def main(myblob: func.InputStream): logging.info(f"Python blob trigger function processed blob \n" f"Name: {myblob.name}\n" f"Blob Size: {myblob.length} bytes") blob_val = myblob.read() # 第一个存储账号连接串 imagedata_acc_string = os.environ["ImageData_ConnectionString"] # 第一个存储账号容器名 imagedata_acc_container = os.environ["ImageContainerName"] blob_service_client = BlobServiceClient.from_connection_string(imagedata_acc_string) container_client = blob_service_client.get_container_client(imagedata_acc_container) # 第二个存储账号相关配置 inferencedata_acc_name = os.environ['INFERENCEDATA_ACCOUNT_NAME'] inferencedata_acc_key = os.environ['INFERENCEDATA_ACCOUNT_KEY'] inferencedata_imagedata_acc_container = os.environ['INFERENCEDATA_ACCOUNT_CONTAINER'] . . . . # 读取触发的图像blob topview_blob = blob_val # 下载对应JSON文件 try: blob_client = container_client.get_blob_client(jsonfilepath) streamdownloader = blob_client.download_blob() jsondata = json.loads(streamdownloader.readall()) logging.info(f"date ---- {jsondata['date']}") logging.info(f" -----Json data downloaded-------") except Exception as Argument: logging.exception("Error downloading json blob") """ 业务逻辑: 1. 从图像存储账号读取JSON数据 2. 判断推理存储账号中是否存在对应JSON文件:不存在则新建,存在则创建blob客户端读取已有文件 3. 将从图像存储读到的JSON数据追加到推理存储的对应文件中 4. 上传更新后的数据到推理存储账号 """ . . . imagejson_data = jsondata infblob_name = jsondata['date'].replace("/","_") + ".csv" # 推理存储账号连接串 infdata_acc_string = os.environ["INFERENCE_ACCOUNT_CONN_STRING"] # 推理存储账号容器名 infdata_acc_container = os.environ['INFERENCEDATA_ACCOUNT_CONTAINER'] infblob_service_client = BlobServiceClient.from_connection_string(infdata_acc_string) infblob_client = infblob_service_client.get_blob_client( container=infdata_acc_container, blob=infblob_name) if not infblob_client.exists(): infblob_client.create_append_blob( container=infdata_acc_container, blob=infblob_name) else: infblob_client.append_block(imagejson_data,length=len(imagejson_data))
已完成配置
host.json配置
{ "version": "2.0", "logging": { "applicationInsights": { "samplingSettings": { "isEnabled": true, "excludedTypes": "Request" } } }, "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[2.*, 3.0.0)" } }
所有需要的环境变量已经在local.settings.json中定义完成。
function.json配置
{ "scriptFile": "src/main.py", "bindings": [ { "name": "myblob", "type": "blobTrigger", "direction": "in", "path": <path-where-image-files-are>, "connection": "ImageData_ConnectionString" } ] }
问题描述
已知该函数为Blob触发类型,但不清楚本地测试方法;尝试在代码中添加断点做本地调试时,断点始终无法命中,函数直接执行结束,无法逐段运行排查问题。
解决方法
- 先排查基础环境问题:本地安装3.x及以上版本的Azure Functions Core Tools,安装和函数运行时匹配的Python版本,VS Code需安装官方Azure Functions扩展,重点确认VS Code当前选中的Python解释器,和你安装函数依赖包的虚拟环境是同一个,80%的断点不命中问题都是解释器选混了导致的。
- 纠正本地触发逻辑:Blob触发类型的函数本地调试时,不需要手动模拟传参启动。按F5启动调试后,等终端输出函数宿主启动成功、触发器已成功绑定目标存储容器的日志后,直接往
ImageData_ConnectionString对应的存储账号、绑定路径下的容器里上传一个测试图片,函数会自动触发,此时断点就能正常命中。 - 校验文件路径配置:检查
function.json里的scriptFile配置值src/main.py是否正确——路径是相对于存放host.json的函数根目录计算的,如果根目录下没有src文件夹、或者main.py不在对应路径下,函数运行的不是你加了断点的文件,断点自然不会生效。 - 检查断点位置有效性:不要把断点打在空行、注释行、模块导入行上,要打在
main函数内的可执行代码行(比如blob_val = myblob.read()这行)。如果启动调试后断点显示为空心,说明当前加载的代码和编辑器里的代码不一致,重启调试会话、重载VS Code窗口即可解决。 - 命令行调试注意事项:如果不用VS Code的F5调试,而是直接用
func start命令启动函数,默认不会开启调试端口,需要附加--debug参数指定调试端口,再用编辑器附加到对应进程,才能捕获断点。 - 排查存储权限问题:本地用的存储连接字符串需要有完整的读写、监听权限,不要用权限不全的SAS令牌,不然Functions Core Tools无法正常监听blob变更,触发器不会正常工作,看起来就像函数直接跑完没有停留。
内容的提问来源于stack exchange,提问作者Sulphur
相关产品推荐
相关产品推荐

