経緯
こちらのサイトを参考にFunctionsとcosmosDBの接続をPythonV2で試していてエラーに遭遇しました。
エラーメッセージ
エラーメッセージは下記の通り。
Result: Failure Exception: TypeError: BindingApi.cosmos_db_output() missing 2 required positional arguments: 'connection' and 'container_name'
connection
とcontainer_name
の引数がない。とのエラーみたいです。
エラー箇所
エラー箇所はcosmosDBと接続を定義している下記の部分でした。
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database",
collection_name="my-container", connection_string_setting="CosmosDbConnectionString")
ここにエラーメッセージの通りconnection
とcontainer_name
がないといけない。
引数が足りないのは分かるが、引数の値に何を設定するかわからなかったので調査。
原因
原因はExtensionBundle(バインディング拡張機能)のバージョンの問題でした。
サイトの手順通り進めていくとhost.json
は下記のようになっていました。
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
versionの部分が "[4.*, 5.0.0)"
。
つまり、version4になっているらしいです。
そして、エラーメッセージが出るのはversion3を使っているときの実装だからみたいです。
しかし、host.json
のextensionBundle
のversion
を"version": "[3.*, 4.0.0)"
に設定して起動してもエラーは変わらず、、、
version4から変更できていないようなので、version4でやることにします。
(version3にする方法が間違っていたら指摘ほしいです。)
対処方法
host.json
の内容はデフォルトのままとし、function_app.py
の実装を変えていきます。
そこで、こちらを参照しました。
内容の一部として@app.cosmos_db_output
の部分の変え方について記載がありました。
connectionStringSetting
→ connection
collectionName
→ containerName
のように変更しなさいとのことでした。
function_app.py
のcosmosDB接続設定部分を変更します。
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database",
container_name="my-container", connection="CosmosDbConnectionString")
変更後のfunction_app.py
は下記の通り
import azure.functions as func
import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database",
container_name="my-container", connection="CosmosDbConnectionString")
def HttpExample(req: func.HttpRequest, msg: func.Out[func.QueueMessage],
outputDocument: func.Out[func.Document]) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
logging.info('Python Cosmos DB trigger function processed a request.')
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:
outputDocument.set(func.Document.from_dict({"id": 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
)