Azure(函数)参数在 Python 中声明,但不在 function.json 中声明

twm*_*wmp 8 python azure azure-functions

我无法理解发生了什么事。我确实遵循所有 Microsoft 文档,实际上甚至不使用我自己的任何脚本/代码。首先,我按照他们的文档创建了 Python 函数。有效。 https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-python?tabs=azure-cli%2Ccmd%2Cbrowser 使用命令将 Azure Functions 连接到 Azure 存储的第二个文档线工具。不可重现。https://learn.microsoft.com/en-us/azure/azure-functions/functions-add-output-binding-storage-queue-cli?pivots=programming-language-python&tabs=bash%2Cbrowser 我确实遵循每一步,但收到错误。

更令人惊讶的是,他们最终向我展示了与第一篇文章不同的代码。我尝试了两个版本——没有一个有效。

这些是来自他们文档的代码。这是他们的 python 脚本代码 ( init .py )

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[func.QueueMessage]) -> str:

    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:
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )
Run Code Online (Sandbox Code Playgroud)

这是 JSON 函数代码:

{
    "scriptFile": "__init__.py",
"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]
}
Run Code Online (Sandbox Code Playgroud)

由于他们没有发布完整版本的代码,我添加了括号等内容。如果你想要文档引用,他们就是这么说的:

尽管一个函数只能有一个触发器,但它可以有多个输入和输出绑定,这使你可以连接到其他 Azure 服务和资源,而无需编写自定义集成代码。您可以在函数文件夹中的 function.json 文件中声明这些绑定。从上一个快速入门中,HttpExample 文件夹中的 function.json 文件在绑定集合中包含两个绑定:

"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }
Run Code Online (Sandbox Code Playgroud)

每个绑定至少有一个类型、一个方向和一个名称。在上面的示例中,第一个绑定的类型为 httpTrigger,方向为 in。对于 in 方向,名称指定由触发器调用时发送到函数的输入参数的名称。

集合中的第二个绑定是 http 类型,方向为 out,在这种情况下,特殊名称 $return 指示此绑定使用函数的返回值而不是提供输入参数。

要从此函数写入 Azure 存储队列,请添加名称为 msg 的类型队列的出绑定,如下面的代码所示:

"bindings": [
  {
    "authLevel": "anonymous",
    "type": "httpTrigger",
    "direction": "in",
    "name": "req",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "$return"
  },
  {
    "type": "queue",
    "direction": "out",
    "name": "msg",
    "queueName": "outqueue",
    "connection": "AzureWebJobsStorage"
  }
]
Run Code Online (Sandbox Code Playgroud)

在本例中,msg 作为输出参数提供给函数。对于队列类型,还必须在queueName 中指定队列的名称,并在connection 中提供Azure 存储连接的名称(来自local.settings.json)。

因此,即使此代码已发布在文档中,它似乎也无法正常工作。或者他们的 python 代码不起作用。我不知道。

我试着跟随他们的脚步。我还尝试复制粘贴他们的新版本代码(与原始代码略有不同)但没有任何效果我仍然收到此错误(我更改了一些我怀疑敏感的元素)

(.venv) C:\Users\usr\LocalFunctionProj>func start
Found Python version 3.8.5 (py).

Azure Functions Core Tools
Core Tools Version:       3.0.3160 Commit hash: 00aa7f49cc5c5f15241a5e6e5363256f19ceb980
Function Runtime Version: 3.0.14916.0


Functions:

        HttpExample: [GET,POST] http://localhost:8072/api/HttpExample

For detailed output, run func with --verbose flag.
[2020-12-27T08:45:11.912Z] Worker process started and initialized.
[2020-12-27T08:45:12.048Z] Worker failed to function id ebece17c-3077-4f78-bcca-d46565cef86c.
[2020-12-27T08:45:12.050Z] Result: Failure
Exception: FunctionLoadError: cannot load the HttpExample function: the following parameters are declared in Python but not in function.json: {'msg'}
Stack:   File "D:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.8\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 272, in _handle__function_load_request
    self._functions.add_function(
  File "D:\Program Files\Microsoft\Azure Functions Core Tools\workers\python\3.8\WINDOWS\X64\azure_functions_worker\functions.py", line 112, in add_function
    raise FunctionLoadError(
.
[2020-12-27T08:45:16.457Z] Host lock lease acquired by instance ID '000000000000000000000000AF616381'.
Run Code Online (Sandbox Code Playgroud)

我真的无法理解他们自己的代码如何不起作用。我想做的只是学习如何将 python 脚本部署到 Azure,我没想到这是一个如此大的挑战。

这是我更新的 python init .py 代码在示例答案后的样子: 初始化.py

这是示例答案后更新后的 function.json 代码的样子:

函数.js

这就是 location.setting 的样子(敏感信息已更改) 位置设置

这就是 host.js 的样子 主机.js

1_1*_*1_1 4

尝试下面,它会正常工作:

host.json

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  }
}
Run Code Online (Sandbox Code Playgroud)

__init__.py

import logging

import azure.functions as func


def main(req: func.HttpRequest, msg: func.Out[str]) -> func.HttpResponse:
    msg.set("This is test. 1227")
    return func.HttpResponse("This is a test.")
Run Code Online (Sandbox Code Playgroud)

function.json

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureStorageQueuesConnectionString"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureStorageQueuesConnectionString":"DefaultEndpointsProtocol=https;AccountName=0730bowmanwindow;AccountKey=xxxxxx==;EndpointSuffix=core.windows.net"
  }
}
Run Code Online (Sandbox Code Playgroud)