3
votes

I cannot understand what is going on. I literally follow all Microsoft docs and in fact don't even use any of my own scripts/codes. Firstly, I followed their docs to create Python function. It worked. https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-python?tabs=azure-cli%2Ccmd%2Cbrowser Second docs to connect Azure Functions to Azure Storage using command line tools. Are not reproducible. https://docs.microsoft.com/en-us/azure/azure-functions/functions-add-output-binding-storage-queue-cli?pivots=programming-language-python&tabs=bash%2Cbrowser I literally follow every step, yet receive error.

What is more surprising is that they end up showing me different codes from first article. I tried both versions --none worked.

These are the codes literally from their docs. This is their code for python script (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
        )

And this is JSON function code:

{
    "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"
  }
]
}

Since they didn't post full version of code I added stuff like brackets. If you want docs citation that's what they say:

Although a function can have only one trigger, it can have multiple input and output bindings, which let you connect to other Azure services and resources without writing custom integration code. You declare these bindings in the function.json file in your function folder. From the previous quickstart, your function.json file in the HttpExample folder contains two bindings in the bindings collection:

"scriptFile": "__init__.py",
"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "$return"
    }

Each binding has at least a type, a direction, and a name. In the example above, the first binding is of type httpTrigger with the direction in. For the in direction, name specifies the name of an input parameter that's sent to the function when invoked by the trigger.

The second binding in the collection is of type http with the direction out, in which case the special name of $return indicates that this binding uses the function's return value rather than providing an input parameter.

To write to an Azure Storage queue from this function, add an out binding of type queue with the name msg, as shown in the code below:

"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"
  }
]

In this case, msg is given to the function as an output argument. For a queue type, you must also specify the name of the queue in queueName and provide the name of the Azure Storage connection (from local.settings.json) in connection.

So even though this code was posted in docs it doesn't seem to work properly. OR their python code is not working. I don't know.

I tried to just follow their steps. I also tried to copy-paste their new version of code (that varied a little from original) But nothing works I still get this error (I changed few elements that I suspect to be sensitive)

(.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'.

I really cannot understand how their own code doesn't work. All I wanted to do is to learn how to deploy my python scripts to Azure, I didn't expect it to be such a big challenge.

This is how my updated python init.py code looks like after example answer: init.py

This is how updated function.json code looks like after example answer:

function.js

This is how location.setting looks like (with sensitive info changed) location.setting

This is how host.js look like host.js

1
Comments are not for extended discussion; this conversation has been moved to chat.Samuel Liew

1 Answers

1
votes

Try below and it will works fine:

host.json

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

__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.")

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"
    }
  ]
}

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureStorageQueuesConnectionString":"DefaultEndpointsProtocol=https;AccountName=0730bowmanwindow;AccountKey=xxxxxx==;EndpointSuffix=core.windows.net"
  }
}